使用JLayeredPane + JScrollPane剪切问题

时间:2016-11-09 16:46:57

标签: java swing jscrollpane jlayeredpane

场景:在JScrollPane的视口中,我有多个JLayeredPane。每个JLayeredPane至少有一个JPanel带有图片(由paintComponent设置)。

问题:没有看到(下面的代码)很难解释:滚动JScrollPane时,JLayeredPane内的图像完全不在内部未绘制JScrollPane区域。

如果我继续滚动,最终JLayeredPane将完全位于JScrollPane区域,并且会绘制图像。

为什么我认为问题出在JLayeredPane 如果我将JLayeredPane替换为JPane,则问题就消失了。 提供的代码可以显示两种情况。设置公共类的第一个也是唯一的静态变量:public static boolean forceProblem = true来控制它。

问题:我做错了什么或怎么做才能解决问题?我需要继续使用JLayeredPane(或任何其他可以做同样的事情)。

重现问题:

  1. 运行以下代码。

  2. 完全向下滚动垂直条。

  3. 向右滚动水平条:问题:图像上方没有加载

  4. 慢慢向上滚动垂直条:图像在完全进入滚动区域时加载。

  5. 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 个答案:

答案 0 :(得分:1)

将JPanel添加到JLayeredPane后使用SetBounds解决了问题:

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