Java JLabel extend to create a scrollable label

Description

Java JLabel extend to create a scrollable label

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.Scrollable;
import javax.swing.SwingConstants;

class ScrollablePicture extends JLabel implements Scrollable, MouseMotionListener {
   private int maxUnitIncrement = 1;
   private boolean missingPicture = false;

   public ScrollablePicture(int m) {
      missingPicture = true;//w w  w.j  a  v  a2  s.c  o m
      setText("No picture found.");
      setHorizontalAlignment(CENTER);
      setOpaque(true);
      setBackground(Color.white);
      maxUnitIncrement = m;

      // Let the user scroll by dragging to outside the window.
      setAutoscrolls(true); // enable synthetic drag events
      addMouseMotionListener(this); // handle mouse drags
   }

   public void mouseMoved(MouseEvent e) {
   }

   public void mouseDragged(MouseEvent e) {
      Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
      scrollRectToVisible(r);
   }

   public Dimension getPreferredSize() {
      if (missingPicture) {
         return new Dimension(320, 480);
      } else {
         return super.getPreferredSize();
      }
   }

   public Dimension getPreferredScrollableViewportSize() {
      return getPreferredSize();
   }

   public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
      int currentPosition = 0;
      if (orientation == SwingConstants.HORIZONTAL) {
         currentPosition = visibleRect.x;
      } else {
         currentPosition = visibleRect.y;
      }

      if (direction < 0) {
         int newPosition = currentPosition - (currentPosition / maxUnitIncrement) * maxUnitIncrement;
         return (newPosition == 0) ? maxUnitIncrement : newPosition;
      } else {
         return ((currentPosition / maxUnitIncrement) + 1) * maxUnitIncrement - currentPosition;
      }
   }

   public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
      if (orientation == SwingConstants.HORIZONTAL) {
         return visibleRect.width - maxUnitIncrement;
      } else {
         return visibleRect.height - maxUnitIncrement;
      }
   }

   public boolean getScrollableTracksViewportWidth() {
      return false;
   }

   public boolean getScrollableTracksViewportHeight() {
      return false;
   }

   public void setMaxUnitIncrement(int pixels) {
      maxUnitIncrement = pixels;
   }
}

class Corner extends JComponent {
   protected void paintComponent(Graphics g) {
      g.setColor(new Color(230, 163, 4));
      g.fillRect(0, 0, getWidth(), getHeight());
   }
}

class Rule extends JComponent {
   public static final int INCH = Toolkit.getDefaultToolkit().getScreenResolution();
   public static final int HORIZONTAL = 0;
   public static final int VERTICAL = 1;
   public static final int SIZE = 35;

   public int orientation;
   private int increment;
   private int units;

   public Rule(int o) {
      orientation = o;
      setIncrementAndUnits();
   }

   private void setIncrementAndUnits() {

      units = (int) ((double) INCH / (double) 2.54); // dots per centimeter
      increment = units;

   }

   public int getIncrement() {
      return increment;
   }

   public void setPreferredHeight(int ph) {
      setPreferredSize(new Dimension(SIZE, ph));
   }

   public void setPreferredWidth(int pw) {
      setPreferredSize(new Dimension(pw, SIZE));
   }

   protected void paintComponent(Graphics g) {
      Rectangle drawHere = g.getClipBounds();

      g.setColor(Color.white);
      g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height);

      g.setColor(Color.black);

      int end = 0;
      int start = 0;
      int tickLength = 0;
      String text = null;

      if (orientation == HORIZONTAL) {
         start = (drawHere.x / increment) * increment;
         end = (((drawHere.x + drawHere.width) / increment) + 1) * increment;
      } else {
         start = (drawHere.y / increment) * increment;
         end = (((drawHere.y + drawHere.height) / increment) + 1) * increment;
      }

      if (start == 0) {
         text = "cm";
         tickLength = 10;
         if (orientation == HORIZONTAL) {
            g.drawLine(0, SIZE - 1, 0, SIZE - tickLength - 1);
            g.drawString(text, 2, 21);
         } else {
            g.drawLine(SIZE - 1, 0, SIZE - tickLength - 1, 0);
            g.drawString(text, 9, 10);
         }
         text = null;
         start = increment;
      }

      // ticks and labels
      for (int i = start; i < end; i += increment) {
         if (i % units == 0) {
            tickLength = 10;
            text = Integer.toString(i / units);
         } else {
            tickLength = 7;
            text = null;
         }

         if (tickLength != 0) {
            if (orientation == HORIZONTAL) {
               g.drawLine(i, SIZE - 1, i, SIZE - tickLength - 1);
               if (text != null)
                  g.drawString(text, i - 3, 21);
            } else {
               g.drawLine(SIZE - 1, i, SIZE - tickLength - 1, i);
               if (text != null)
                  g.drawString(text, 9, i + 3);
            }
         }
      }
   }
}

public class Main extends JPanel implements ItemListener {
   private Rule columnView;
   private Rule rowView;
   private JToggleButton isMetric;
   private ScrollablePicture picture;

   public Main() {
      setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));

      // Create the row and column headers.
      columnView = new Rule(Rule.HORIZONTAL);
      rowView = new Rule(Rule.VERTICAL);

      columnView.setPreferredWidth(320);
      rowView.setPreferredHeight(480);

      JPanel buttonCorner = new JPanel(); // use FlowLayout
      isMetric = new JToggleButton("cm", true);
      isMetric.setFont(new Font("SansSerif", Font.PLAIN, 11));
      isMetric.setMargin(new Insets(2, 2, 2, 2));
      isMetric.addItemListener(this);
      buttonCorner.add(isMetric);

      // Set up the scroll pane.
      picture = new ScrollablePicture(columnView.getIncrement());
      JScrollPane pictureScrollPane = new JScrollPane(picture);
      pictureScrollPane.setPreferredSize(new Dimension(300, 250));
      pictureScrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.black));

      pictureScrollPane.setColumnHeaderView(columnView);
      pictureScrollPane.setRowHeaderView(rowView);

      pictureScrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, buttonCorner);
      pictureScrollPane.setCorner(JScrollPane.LOWER_LEFT_CORNER, new Corner());
      pictureScrollPane.setCorner(JScrollPane.UPPER_RIGHT_CORNER, new Corner());

      // Put it in this panel.
      add(pictureScrollPane);
      setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
   }

   public void itemStateChanged(ItemEvent e) {
      picture.setMaxUnitIncrement(rowView.getIncrement());
   }

   public static void main(String[] args) {
      JFrame frame = new JFrame("ScrollDemo");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      JComponent newContentPane = new Main();
      newContentPane.setOpaque(true); // content panes must be opaque
      frame.setContentPane(newContentPane);

      frame.pack();
      frame.setVisible(true);
   }
}



PreviousNext

Related