JComponentBounds

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen

Die Klasse "JComponentBounds" erlaubt es, JComponents zu verschieben und in der Grösse zu verändern. Die Klasse "PictureDemo" weiter unten zeigt ein Anwendungsbeispiel. <code=java> /*

* JComponentBounds.java
* 
* This class aims at making JComponents moveable and resizable.
* 
* author: Andre Uhres
* last update November 23, 2009 at 14:00
*/

import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.plaf.basic.*;

public class JComponentBounds extends JInternalFrame {

   private JComponent componentsContainer;
   private boolean focused;
   private int deltaX;
   private int deltaY;
   private JComponent comp;
   private static final Color TRANSPARENT = new Color(0.0f, 0.0f, 0.0f, 0.0f);
   public static final int MARGIN = 5;
   private KeyAdapter kl;
   private MouseInputAdapter ml;
   private ComponentAdapter cl;
   private boolean snapToGrid;
   public JComponentBounds() {
       this(new JLabel("jComponentBounds"));
   }
   public JComponentBounds(final JComponent comp) {
       this(comp, 0, 0, false);
   }
   public JComponentBounds(final JComponent comp, final boolean focused) {
       this(comp, 0, 0, focused);
   }
   public JComponentBounds(final JComponent comp, final int x, final int y, final boolean focused) {
       super();
       this.comp = comp;
       this.focused = focused;
       setBounds(x, y, comp.getPreferredSize().width, comp.getPreferredSize().height);
       setResizable(true);
       setVisible(true);
       setOpaque(false);
       setBackground(TRANSPARENT);
       ((BasicInternalFrameUI) getUI()).setNorthPane(null);
       setBorder(BorderFactory.createEmptyBorder(MARGIN, MARGIN, MARGIN, MARGIN));
       comp.setFocusable(true);
       add(comp);
       ml = new MouseInputAdapter() {
           @Override
           public void mousePressed(final MouseEvent e) {
               componentsContainer = (JComponent) getParent();
               deltaX = e.getPoint().x;
               deltaY = e.getPoint().y;
               e.setSource(JComponentBounds.this);
               //componentsContainer might use the event 
               //to take hidden components to the top:
               componentsContainer.dispatchEvent(e);
           }
           @Override
           public void mouseReleased(final MouseEvent e) {
               componentsContainer = (JComponent) getParent();
               e.setSource(JComponentBounds.this);
               //componentsContainer might use the event 
               //to take hidden components to the top:
               componentsContainer.dispatchEvent(e);
           }
           @Override
           public void mouseDragged(final MouseEvent e) {
               if (!JComponentBounds.this.isFocused()) {
                   return;
               }
               componentsContainer = (JComponent) getParent();
               componentsContainer.setComponentZOrder(JComponentBounds.this, 0);
               setLocation(getLocation().x + e.getPoint().x - deltaX,
                       getLocation().y + e.getPoint().y - deltaY);
               componentsContainer.repaint();
               setZorderAllowed(false);//let dragged component on the top
           }
       };
       kl = new KeyAdapter() {
           @Override
           public void keyPressed(final KeyEvent e) {
               componentsContainer = (JComponent) getParent();
               //componentsContainer might use the event 
               //to delete the component:
               componentsContainer.dispatchEvent(e);
           }
       };
       cl = new ComponentAdapter() {
           @Override
           public void componentResized(final ComponentEvent e) {
               adaptZorder(e);
               componentsContainer = (JComponent) e.getSource();
               componentsContainer.revalidate();
           }
           @Override
           public void componentMoved(final ComponentEvent e) {
               componentsContainer = (JComponent) e.getSource();
               componentsContainer.revalidate();
           }
       };
       addAllListeners();
   }
   @Override
   public void reshape(final int x, final int y, final int width, final int height) {
       if (snapToGrid) {
           int x2 = x / MARGIN * MARGIN;
           int y2 = y / MARGIN * MARGIN;
           int w2 = width / MARGIN * MARGIN;
           int h2 = height / MARGIN * MARGIN;
           if (x2 != x && w2 != width) {
               w2 += MARGIN;
           }
           if (y2 != y && h2 != height) {
               h2 += MARGIN;
           }
           super.reshape(x2, y2, w2, h2);
       }else{
           super.reshape(x, y, width, height);
       }
   }
   public boolean isSnapToGrid() {
       return snapToGrid;
   }
   public void setSnapToGrid(final boolean snapToGrid) {
       this.snapToGrid = snapToGrid;
   }
   //Must be overridden to let dragged component on the top:
   public void setZorderAllowed(final boolean b) {
   }
   public void adaptZorder(final ComponentEvent e) {
       componentsContainer = (JComponent) getParent();
       Object source = e.getSource();
       if (componentsContainer instanceof ComponentsContainer && source instanceof JComponentBounds) {
           ((ComponentsContainer) componentsContainer).adaptZorder(source, new Point(0, 0));
       }
   }
   private void addAllListeners() {
       comp.addMouseListener(ml);
       comp.addMouseMotionListener(ml);
       comp.addKeyListener(kl);
       addComponentListener(cl);
   }
   public void removeAllListeners() {
       comp.removeMouseListener(ml);
       comp.removeMouseMotionListener(ml);
       comp.removeKeyListener(kl);
       removeComponentListener(cl);
   }
   public void setComponent(final JComponent comp) {
       //remove old component:
       removeAllListeners();
       remove(this.comp);
       //add new component:
       this.comp = comp;
       comp.setFocusable(true);
       add(comp);
       addAllListeners();
   }
   public void setFocused(final boolean focused) {
       this.focused = focused;
       repaint();
   }
   public boolean isFocused() {
       return focused;
   }

} </code=java>

<code=java> import container.JComponentBounds; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.io.*; import java.util.*; import javax.imageio.*; import javax.swing.*;

class GUI extends JFrame implements Observer {

   private PictureDemo demo;
   private JComponent picture;
   private JComponentBounds pictureBounds;
   private GUI frame;
   private Image image;
   public GUI(final PictureDemo demo) {
       super();
       this.demo = demo;
       this.init();
   }
   private void init() {
       frame = this;
       setTitle("Demo: click to load picture");
       setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
       setSize(800, 600);
       setLocationRelativeTo(null);
       addMouseListener(new MouseAdapter() {
           @Override
           public void mousePressed(MouseEvent e) {
               FileDialog fileDialog = new FileDialog(frame);
               fileDialog.setVisible(true);
               String dir = fileDialog.getDirectory();
               String file = fileDialog.getFile();
               if (dir != null && file != null) {
                   demo.loadPicture(dir + file);
               }
           }
       });
       //configure picture:
       setLayout(null);
       picture = new JLabel() {
           @Override
           protected void paintComponent(Graphics g) {
               super.paintComponent(g);

// g.drawImage(image, 0, 0, this);

               g.drawImage(image, 0, 0, pictureBounds.getWidth(), pictureBounds.getHeight(), this);
           }
       };
       picture.setPreferredSize(new Dimension(100, 100));
       pictureBounds = new JComponentBounds(picture, 10, 10, true);
       pictureBounds.setMinimumSize(new Dimension(40, 20));

// pictureBounds.setSnapToGrid(true);

       add(pictureBounds);
   }
   public void update(final Observable observable, final Object arg) {
       image = (Image) arg;
       if (image == null) {
           JOptionPane.showMessageDialog(this, "Picture not found");
       } else {
           pictureBounds.setSize(image.getWidth(null), image.getHeight(null));
           picture.setOpaque(true);
           picture.setBackground(Color.LIGHT_GRAY);
           picture.repaint();
       }
   }

}

class PictureStorage extends Observable {

   private BufferedImage data;
   public PictureStorage() {
   }
   public void loadPicture(final String filename) {
       System.out.println("loading " + filename);
       SwingWorker<BufferedImage, Void> loadPicture = new SwingWorker<BufferedImage, Void>() {
           @Override
           protected BufferedImage doInBackground() throws Exception {
               try {
                   data = ImageIO.read(new File(filename));
               } catch (IOException ex) {
                   ex.printStackTrace();
               }
               return data;
           }
           @Override
           protected void done() {
               setChanged();
               notifyObservers(data); //sends change notification to the view
           }
       };
       loadPicture.execute();
   }

}

public class PictureDemo {

   private PictureStorage model;
   public PictureDemo() {
       model = new PictureStorage();
       GUI gui = new GUI(this);
       model.addObserver(gui);
       gui.setVisible(true);
   }
   public void loadPicture(String file) {
       model.loadPicture(file);
   }
   public static void main(final String[] args) {
       Runnable gui = new Runnable() {
           @Override
           public void run() {
               new PictureDemo();
           }
       };
       //GUI must start on EventDispatchThread:
       SwingUtilities.invokeLater(gui);
   }

} </code=java>