import java.awt.*; import java.awt.event.*; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.awt.event.ComponentAdapter; import java.net.URL; import javax.swing.*; /** * ImageDisplay is a test program for DoubleHeadedScrollbar. * It displays an image with a horizontal DoubleHeadedScrollbar * and a vertical normal scrollbar. The user can pan around as usual, * or use the double-headed thumb to magnify the image. */ public class ImageDisplay extends JComponent { // UI components private JComponent imageComponent; private JScrollBar vertical; private JScrollBar horizontal; // image being displayed private Image image; // image dimensions in pixels private int width, height; // part of image currently visible in the imageComponent, // in pixel coordinates private int x1; private int x2; private int y1; private int y2; /** * Make an ImageDisplay. * @param img Image to display */ public ImageDisplay(Image img) { // save image this.image = img; width = image.getWidth(null); height = image.getHeight(null); // create the image-display component imageComponent = new JComponent() { protected void paintComponent(Graphics g) { super.paintComponent(g); Dimension size = getSize(); g.drawImage(image, 0, 0, size.width, size.height, x1, y1, x2, y2, null); } }; imageComponent.setPreferredSize(new Dimension(width/2, height/2)); // create the scrollbars horizontal = new DoubleHeadedScrollbar(0, 50, 0, 100); vertical = new JScrollBar(JScrollBar.VERTICAL, 0, 50, 0, 100); updateFrom(horizontal); // listen to the scrollbars for changes AdjustmentListener listener = new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent e) { JScrollBar scrollbar = (JScrollBar)e.getSource(); updateFrom(scrollbar); } }; horizontal.addAdjustmentListener(listener); vertical.addAdjustmentListener(listener); // lay out the image and the scrollbars. setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.fill = GridBagConstraints.BOTH; c.weightx = 1; c.weighty = 1; add(imageComponent, c); c.gridx = 1; c.gridy = 0; c.fill = GridBagConstraints.VERTICAL; c.weightx = 0; c.weighty = 1; add(vertical, c); c.gridx = 0; c.gridy = 1; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1; c.weighty = 0; add(horizontal, c); } // Called when one of the scrollbars is manipulated. // Pans and magnifies the image as appropriate. private void updateFrom(JScrollBar scrollbar) { // first, copy the visible extent to the other scrollbar ((scrollbar == horizontal) ? vertical : horizontal) .setVisibleAmount (scrollbar.getVisibleAmount()); double xRange = horizontal.getMaximum() - horizontal.getMinimum(); x1 = (int) Math.round(horizontal.getValue() * width / xRange); x2 = x1 + (int) Math.round(horizontal.getVisibleAmount() * width / xRange); double yRange = vertical.getMaximum() - vertical.getMinimum(); y1 = (int) Math.round(vertical.getValue() * height / yRange); y2 = y1 + (int) Math.round(vertical.getVisibleAmount() * height / yRange); repaint(); } /** * Main method. Pops up a window displaying an ImageDisplay on * a sample image. * @param args command line arguments; ignored. */ public static void main(String[] args) { // uncomment the following code to use the // local platform's look-and-feel // try { // String lookAndFeel = UIManager.getSystemLookAndFeelClassName(); // UIManager.setLookAndFeel (lookAndFeel); // } catch (Exception e) { // e.printStackTrace(); // } final JFrame f = new JFrame("Double-Headed Scrollbar"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container c = f.getContentPane(); URL url = ImageDisplay.class.getResource("Stephansdom.jpg"); Image img = new ImageIcon(url).getImage(); c.add(new ImageDisplay(img), BorderLayout.CENTER); f.pack(); f.show(); } }