2016-11-09 97 views
1

方案:JScrollPane的視口內,我有多個JLayeredPane。每個JLayeredPane至少有一個JPanel與一個圖像(由paintComponent設置)。JLayeredPane + JScrollPane裁剪問題

問題:硬,沒有看到(下面的代碼)來解釋:滾動JScrollPane時,不屬於完全的JScrollPane區域內的JLayeredPane S的內部的圖像不繪製。

如果我繼續滾動,最終JLayeredPane將完全位於JScrollPane區域,並繪製圖像。

爲什麼我認爲問題出在JLayeredPane 如果我將JLayeredPane替換爲JPane,問題就消失了。 提供的代碼可以顯示兩種情況。設置公共類的第一個,也是唯一的靜態變量:public static boolean forceProblem = true來控制它。

問題:我在做什麼錯誤或如何解決問題?我需要繼續使用JLayeredPane(或其他可以做同樣的事情)。

再現問題:

  1. 運行下面的代碼。

  2. 一直向下滾動垂直條。

  3. 滾動單槓一路右:問題:圖像的上線的arent加載

  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添加的JPanel後的JLayeredPane的解決了這個問題:

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)); 
    } 
}