2016-11-09 8 views
1

シナリオ:JScrollPaneのビューポート内には複数のJLayeredPaneがあります。各JLayeredPaneには、少なくとも1つの画像(paintComponentで設定)を持つJPanelがあります。JLayeredPane + JScrollPaneのクリッピング問題

問題:ハード(以下コード)を見ることなく説明するために:JScrollPaneをスクロールしたとき、完全にJScrollPane領域の内側ではありませんJLayeredPaneの内部の画像が描かれていません。

スクロールを続けると、JLayeredPaneは完全にJScrollPaneになり、画像が描画されます。

なぜ問題はJLayeredPaneにあると思いますか? JLayeredPaneJPaneに置き換えた場合、問題はなくなりました。 提供されたコードは、両方のケースを示すことができます。パブリッククラスの最初の唯一の静的変数:public static boolean forceProblem = trueをこれを制御するように設定します。

質問:問題を解決するために何が間違っているのですか? JLayeredPane(または同じことをすることができる他のもの)を使用し続ける必要があります。

問題を再現:

  1. は、以下のコードを実行します。

  2. 垂直バーを完全に下にスクロールします。

  3. スクロールすべての道は右水平バー:問題:画像の上の線はゆっくりと垂直バーをスクロールアップ

  4. をロードアレントは:イメージは、ときに完全にスクロール領域にロードされています。


import java.awt.*; 
import javax.swing.*; 

class MYimagePanel extends JPanel { 
    public Image image; 

    public MYimagePanel(Image img) { 
     this.image = img; 
     this.setLayout(null); 

     this.setBounds(0, 0, 1, 1); 
    } 

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

     this.setSize(100 , 100); 
     this.setPreferredSize(new Dimension(100 , 100));  

     g.drawImage(this.image , 0 , 0 , 100 , 100 , null); 
    } 
} 

class MYcomposedImagePanel extends JLayeredPane { 
    public MYcomposedImagePanel(Image img) { 
     this.setLayout(null); 

     MYimagePanel myImgPane = new MYimagePanel(img); 

     this.add(myImgPane); 
     this.setLayer(myImgPane , 1); 

     this.setBounds(0, 0 , 100 , 100); 
     //this.setPreferredSize(new Dimension(100 , 100)); 
    } 
} 






public class ClippingProblem extends JFrame { 
    public static boolean forceProblem = true; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       // Creating Frame 
       JFrame frame = new ClippingProblem(); 

       Container contentPane = frame.getContentPane(); 
       contentPane.setLayout(null); 

       // ScrollPane viewport 
       JLayeredPane imagesPane = new JLayeredPane(); 
       imagesPane.setLayout(null); 
       imagesPane.setLocation(0, 0); 
       imagesPane.setPreferredSize(new Dimension(2000,2000)); 

       // ScrollPane 
       JScrollPane scrollPane = new JScrollPane(imagesPane ); 
       scrollPane.setBounds(0, 0, 1000 , 700); 
       scrollPane.getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE); 

       contentPane.add(scrollPane); 

       // Add Images 
       int offset = 0; 
       MYcomposedImagePanel composedImage; 
       MYimagePanel myImagePanel; 
       ImageIcon icon = new ImageIcon("image.png"); 

       for(int y = 0 ; y < 1900 ; y = y + 100) { 
        for(int x = 0 ; x < 1900 ; x = x + 100) { 
         if(forceProblem == true) { 
          composedImage = new MYcomposedImagePanel(icon.getImage()); 
          composedImage.setBounds(x + offset , y , 100 , 100); 
         imagesPane.add(composedImage); 
        } else { 
         myImagePanel = new MYimagePanel(icon.getImage() ); 
         myImagePanel.setBounds(x + offset , y , 100 , 100); 
         imagesPane.add(myImagePanel); 
        } 
        offset += 10; 
       } 
       // Set visible 
       frame.setVisible(true); 
      } 
     }) ; 
    } 


    public ClippingProblem() { 
     setSize(1024, 768); 

     setTitle("Clipping Problem"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setLocationRelativeTo(null); 
    } 
} 

使う画像: Image

答えて

1

SetBoundsを使用してのJLayeredPaneへのJPanelを追加した後は、この問題を解決:

class MYcomposedImagePanel extends JLayeredPane { 
    public MYcomposedImagePanel(Image img) { 
     this.setLayout(null); 

     MYimagePanel myImgPane = new MYimagePanel(img); 

     this.add(myImgPane); 
     this.setLayer(myImgPane , 1); 

     myImgPane.setBounds(0, 0 , 100 , 100); // <<--- NEW LINE ---- 

     this.setBounds(0, 0 , 100 , 100); 
     //this.setPreferredSize(new Dimension(100 , 100)); 
    } 
} 
関連する問題