これは実際の例ですが、java-image-scalingライブラリ (LGPL) が必要です。これは、プレビュー イメージのスムーズなスケーリングに使用されます。そうしないと、完全に台無しになったイメージが得られます。
public static void main ( String[] args )
{
final JFrame mainFrame = new JFrame ();
JPanel content = new JPanel ( new GridLayout ( 20, 20 ) );
for ( int i = 0; i < 20; i++ )
{
for ( int j = 0; j < 20; j++ )
{
content.add ( new JLabel ( "Test " + i + ":" + j )
{
{
setBorder ( BorderFactory.createEmptyBorder ( 20, 20, 20, 20 ) );
}
} );
}
}
final JScrollPane pane = new JScrollPane ( content );
pane.setCorner ( JScrollPane.LOWER_TRAILING_CORNER, new JButton ()
{
{
final JButton button = this;
addActionListener ( new ActionListener ()
{
public void actionPerformed ( ActionEvent e )
{
JComponent comp = ( JComponent ) pane.getViewport ().getView ();
Dimension size = comp.getSize ();
Rectangle viewRect = comp.getVisibleRect ();
// Drawing preview
BufferedImage image = new BufferedImage ( size.width, size.height,
BufferedImage.TYPE_INT_RGB );
Graphics2D g2d = image.createGraphics ();
comp.print ( g2d );
g2d.dispose ();
// Rescaling preview
int width = 200;
int height = comp.getHeight () * width / comp.getHeight ();
BufferedImage rescaled =
new ResampleOp ( width, height ).filter ( image, null );
// Drawing view rect
float diff = (float)width / size.width;
g2d = rescaled.createGraphics ();
g2d.setPaint ( Color.RED );
g2d.drawRect ( Math.round ( viewRect.x * diff ),
Math.round ( viewRect.y * diff ),
Math.round ( viewRect.width * diff ),
Math.round ( viewRect.height * diff ) );
g2d.dispose ();
// Displaying preview
final JDialog preview = new JDialog ( mainFrame );
preview.setUndecorated ( true );
preview.add ( new JLabel ( new ImageIcon ( rescaled ) )
{
{
setBorder ( BorderFactory.createLineBorder ( Color.BLACK ) );
setFocusable ( true );
}
} );
Point los = button.getLocationOnScreen ();
preview.setSize ( width + 2, height + 2 );
preview.setLocation ( los.x - width - 2, los.y - height - 2 );
preview.setVisible ( true );
preview.requestFocus ();
preview.addFocusListener ( new FocusAdapter ()
{
public void focusLost ( FocusEvent e )
{
preview.dispose ();
}
} );
}
} );
}
} );
mainFrame.add ( pane );
mainFrame.setSize ( 600, 600 );
mainFrame.setLocationRelativeTo ( null );
mainFrame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
mainFrame.setVisible ( true );
}
したがって、基本的にはパネルのスナップショットを作成し、それを再スケーリングして、ボタンの近くに開き、フォーカスが失われると閉じる小さなダイアログに配置します。ただし、スナップショットの作成は時間を浪費する可能性がありますが、スクロールペインコンテナー全体のレンダリングされたプレビューを作成するより良い方法はわかりません.プレビューを表示するには何かにペイントする必要があり、それは同じ時間を費やすことを意味します.
また、プレビュー コンポーネントを簡単に変更できるため、プレビュー ダイアログで赤い四角形をドラッグして、表示されている四角形を移動できます :)