2017-03-29 3 views
0

最近、私は少し面倒なことに遭遇するまで、小さなプロジェクトに取り組んできました。Java - paintComponent()は、高解像度の画像を再ペイントするときにプログラムの速度を大幅に遅くします。

ファイル拡張子が「.jpg」および「.png」のファイルが表示されるプログラムによって生成された特定のフォルダが読み込まれます(これが機能するには、ユーザーが手動で行う必要がありますこれらのフォルダに画像を挿入します)。

私が作成したアニメーション部分に達するまで、その部分は機能します。これは、マウスがその上を移動して終了するとアルファ値を変更する特定のRGBA値を持つ矩形です。低解像度の画像では、このアニメーションはスムーズに動作しますが、高解像度の画像では非常に遅く、アニメーションが滑らかに見えません。私をテストする

メインフレームクラス

package seriesorganiser; 

import java.awt.GridLayout; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.io.File; 
import java.io.IOException; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

/** 
* 
* @author Luca Muscat 
*/ 
public class mainFrame { 

    private static boolean check; 
    private static final String DOCUMENTS_LOCATION = System.getProperty("user.home") + "\\Documents"; 

    public static void main(String[] args) throws IOException { 
     check = new File(DOCUMENTS_LOCATION + "\\SeriesOrganiser").exists(); 
     if (!check) { 
      new File(DOCUMENTS_LOCATION + "\\SeriesOrganiser").mkdir(); 
      new File(DOCUMENTS_LOCATION + "\\SeriesOrganiser\\Shows").mkdir(); 
      new File(DOCUMENTS_LOCATION + "\\SeriesOrganiser\\Movies").mkdir(); 
     } 
     JFrame frame = new JFrame("Series Organiser"); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 

     //Layout Handler 
     JPanel container = new JPanel(); 
     //Movies=0, Shows=1. 
     JPanel moviesPanel = new moviesShowsPanel(0); 
     JPanel showsPanel = new moviesShowsPanel(1); 

     container.setLayout(new GridLayout(1, 2)); 
     container.add(moviesPanel); 
     container.add(showsPanel); 

     frame.add(container); 
     frame.pack(); 
    } 
} 

moviesShowsPanel

package seriesorganiser; 

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.io.IOException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.BorderFactory; 
import javax.swing.JPanel; 

/** 
* 
* @author Luca Muscat 
*/ 
public class moviesShowsPanel extends JPanel { 

    int alpha = 255/2; 
    boolean isMouseOver = false; 
    boolean isMouseHover = false; 
    public final static int SHOWS_GENRE = 1; 
    public final static int MOVIES_GENRE = 0; 
    private int genreHolder; 
    public moviesShowsPanel(int genre) { 
     genreHolder=genre; 
     setPreferredSize(new Dimension(600, 600)); 
     setBorder(BorderFactory.createLineBorder(Color.black)); 
     setBackground(Color.LIGHT_GRAY); 

     addMouseListener(new MouseAdapter() { 
      @Override 
      public void mouseEntered(MouseEvent me) { 
       if(!isMouseOver)repaint(); 
       isMouseOver = true; 
      } 

      @Override 
      public void mouseExited(MouseEvent me) { 
       if(isMouseOver)repaint(); 
       isMouseOver = false; 
      } 
     }); 

    } 
    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     scanForImage findImage = new scanForImage(); 
     if (isMouseOver && alpha>10) { 
      alpha-=10;  
     } 
     if(!isMouseOver && alpha<145){ 
      alpha+=10; 
     } 
     try { 
      if(genreHolder==MOVIES_GENRE){ 
       g.drawImage(findImage.findMoviesImage(), 0, 0, getWidth(), getHeight(), null); 
      } 
      if(genreHolder==SHOWS_GENRE){ 
       g.drawImage(findImage.findShowsImage(),0,0,getWidth(),getHeight(),null); 
      } 
     } catch (IOException ex) { 
      Logger.getLogger(moviesShowsPanel.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     g.setColor(new Color(214, 229, 255, alpha)); 
     g.fillRect(0, 0, getWidth(), getHeight()); 
     repaint(); 
    } 
} 

scanForImage

package seriesorganiser; 

import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import javax.imageio.ImageIO; 

/** 
* 
* @author Luca Muscat 
*/ 
public class scanForImage { 
    private static final String DOCUMENTS_LOCATION = System.getProperty("user.home")+"\\Documents"; 
    BufferedImage findMoviesImage() throws IOException{ 
     BufferedImage img = null; 
     File folderMovies = new File(DOCUMENTS_LOCATION+"\\SeriesOrganiser\\Movies"); 
     img=DRY(folderMovies); 
     return img; 
    } 
    BufferedImage findShowsImage()throws IOException{ 
     BufferedImage img=null; 
     File folderShows = new File(DOCUMENTS_LOCATION+"\\SeriesOrganiser\\Shows"); 
     img = DRY(folderShows); 
     return img; 
    } 
    private BufferedImage DRY(File f)throws IOException{ 
     BufferedImage img=null; 
     String filepath=String.valueOf(f); 
     File[] listOfFiles=f.listFiles(); 
     for(File c:listOfFiles){ 
      if(c.isFile()){ 
       if(c.getName().contains(".jpg") || c.getName().contains(".png")){ 
        img=ImageIO.read(new File(filepath+"\\"+c.getName())); 
        break; 
       } 
      } 
     } 
     return img; 
    } 
} 

皆さんがしなければならないことは、 "Documents"フォルダライブラリのSeriesOrganiserというフォルダにあるMoviesとShowsファイルの両方に画像を置くことです。 (ウィンドウズ10)。

コードを批判する気にはならないでしょうが、私は改善がたくさんあることを知っています。

答えて

3

paintComponent()メソッドからのコメントのカップル:

scanForImage findImage = new scanForImage(); 

は、塗装方法でI/Oをしないでください。塗装方法は塗装専用です

repaint(); 

repaint()を起動しないでください。これにより、ペインティング要求がイベントキューに継続的に追加されます。

アニメーションが必要な場合は、Swing Timerを使用してアニメーションをスケジュールします。

g.dispose(); 

メソッドに渡されたGraphicsオブジェクトを破棄しないでください。フレーム上の他のコンポーネントは、このグラフィックを使用することができます。

dispose()メソッドは、paintComponent()メソッド内で作成するGraphicオブジェクトでのみ使用します。

+0

@ LucaMuscatだから、あなたはスイングタイマーを使用しています。 – camickr

+1

@LucaMuscatだから、あなたはスイングタイマーを使用しています。クラスに 'setAlpha(...)'や 'incrementalpha()'や 'decrmentAlpha()'のようなメソッドが必要です。 Timerが起動するたびに、適切なメソッドが呼び出され、アルファ値が更新され、repaint()が呼び出されてイメージの再描画がスケジュールされます。この方法で、コンポーネントの再描画頻度を制御できます。 – camickr

+0

[Java命名規則](http://www.oracle.com/technetwork/java/codeconventions-135099.html)に従うことを忘れないでください。 – Frakcool

関連する問題