シナリオ:JScrollPane
のビューポート内には複数のJLayeredPane
があります。各JLayeredPane
には、少なくとも1つの画像(paintComponent
で設定)を持つJPanel
があります。JLayeredPane + JScrollPaneのクリッピング問題
問題:ハード(以下コード)を見ることなく説明するために:JScrollPane
をスクロールしたとき、完全にJScrollPane
領域の内側ではありませんJLayeredPane
の内部の画像が描かれていません。
スクロールを続けると、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);
}
}