Что бы я тут делал:
1. Иметь панель (холст), единственной обязанностью которой является рисование данного изображения независимо от реального размера изображения в переопределенном методе paintComponent()
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
2. Убедитесь, что предпочтительный размер холста равен реальному размеру изображения.
3. Иметь вторую панель, которая будет служить панелью содержимого фрейма.
4.В нем вы установите JScrollPane
в качестве центра.
5.В области просмотра панели прокрутки будет компонент из шага 1.
6.Добавьте кнопку на панель холста с шага 1. Она будет прокручена вместе с изображением.
7.Добавьте панель содержимого, панель из шага 3, во фрейм и запустите приложение.
EDIT:
Пример кода с добавленной на холст кнопкой, которая всегда остается на своем месте, независимо от положения прокрутки или размера кадра.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class ScrollImageTest extends JPanel {
private static final long serialVersionUID = 1L;
private BufferedImage image;
private JPanel canvas;
public ScrollImageTest() {
try {
this.image = ImageIO.read(new URL("http://interviewpenguin.com/wp-content/uploads/2011/06/java-programmers-brain.jpg"));
}catch(IOException ex) {
Logger.getLogger(ScrollImageTest.class.getName()).log(Level.SEVERE, null, ex);
}
this.canvas = new JPanel() {
private static final long serialVersionUID = 1L;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
};
canvas.add(new JButton("Currently I do nothing"));
canvas.setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
JScrollPane sp = new JScrollPane(canvas);
setLayout(new BorderLayout());
add(sp, BorderLayout.CENTER);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JPanel p = new ScrollImageTest();
JFrame f = new JFrame();
f.setContentPane(p);
f.setSize(400, 300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
});
}
}