场景:在JScrollPane
的视口内,我有多个JLayeredPane
。每个JLayeredPane
至少具有一个带有图像的JPanel
(由paintComponent
设置)。
问题:难以理解,看不见(以下代码):滚动JScrollPane
时,未绘制JLayeredPane
区域内未完全位于JScrollPane
区域内的图像。
如果我继续滚动,最终JLayeredPane
将完全位于JScrollPane
区域,并绘制图像。
为什么我认为问题出在JLayeredPane
中?
如果我将JLayeredPane
替换为JPane
,问题就不存在了。
提供的代码可以显示两种情况。设置公共类的第一个也是唯一的静态变量:public static boolean forceProblem = true
来控制它。
问题:我做错了什么或应该怎么解决?我需要继续使用JLayeredPane
(或其他可以执行相同操作的东西)。
重现问题:
运行下面的代码。
一直向下滚动垂直栏。
一直向右滚动水平栏:问题:已加载图像的最高行
缓慢向上滚动垂直栏:将图像完全加载到“滚动”区域中时,将其加载。
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);
}
}
使用的图片:
最佳答案
在将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 ));
}
}
关于java - JLayeredPane + JScrollPane的剪切问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40512043/