PercentLayout

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen

Hier mal ein Versuch einen LayoutManager zu implementieren, der die übergebenen Komponenten nach prozentualen Werten ausrichten kann.
Es kann sein, dass er sich unter bestimmten Umständen merkwürdig verhält.

Zuerst eine Klasse, die den LayoutManager benutzt: die Demo-Klasse für das PercentLayout.

import java.awt.*;
import javax.swing.*;

public class PercentLayoutDemo {
   public static void main(String[] s) {
      JPanel panel = new JPanel(new PercentLayout());
      JLabel label = new JLabel("Test OUT");
      label.setOpaque(true);
      label.setBackground(Color.GREEN);
      panel.add(label, .25);
      JPanel inner = new JPanel(new PercentLayout(PercentLayout.VERTICAL));
      panel.add(inner);

      label = new JLabel("Test Out");
      label.setOpaque(true);
      label.setBackground(Color.BLUE);
      panel.add(label, .35);

      label = new JLabel("Test IN");
      label.setOpaque(true);
      label.setBackground(Color.ORANGE);
      inner.add(label, .5);
      label = new JLabel("Test IN");
      label.setOpaque(true);
      label.setBackground(Color.DARK_GRAY);
      inner.add(label, .1);
      label = new JLabel("Test IN REST");
      label.setOpaque(true);
      label.setBackground(Color.YELLOW);
      inner.add(label);

      JFrame frame = new JFrame();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.add(panel);
      frame.setBounds(0, 0, 200, 200);
      frame.setVisible(true);
   }
}

Und hier nun der LayoutManager:

import java.awt.*;
import java.util.*;

class PercentLayout implements LayoutManager2 {
   public static final int HORIZONTAL = 0;
   public static final int VERTICAL = 1;

   private int orientation;
   private double sum;
   private List<Component> components;
   private List<Double> weights;

   public PercentLayout() {
      this(HORIZONTAL);
   }

   public PercentLayout(int orientation) {
      this.orientation = orientation;
      this.components = new ArrayList<Component>();
      this.weights = new ArrayList<Double>();
   }

   public Dimension preferredLayoutSize(Container parent) {
      synchronized (parent.getTreeLock()) {
         int w = 0, h = 0;
         for (Component c: components) {
            w += c.getPreferredSize().width;
            h += c.getPreferredSize().height;
         }
         return new Dimension(w, h);
      }
   }

   public Dimension minimumLayoutSize(Container parent) {
      synchronized (parent.getTreeLock()) {
         int w = 0, h = 0;
         for (Component c: components) {
            w += c.getMinimumSize().width;
            h += c.getMinimumSize().height;
         }
         return new Dimension(w, h);
      }
   }

   public void layoutContainer(Container parent) {
      synchronized (parent.getTreeLock()) {
         int w = parent.getWidth();
         int h = parent.getHeight();

         if (this.orientation == HORIZONTAL) {
            int x = 0;
            for (int i=0; i<components.size() ; i++) {
               Component c = components.get(i);
               double weight = weights.get(i);
               int width = (int)(w*weight);
               if (weight==0d)
                  width = (int)(w - w*sum);

               c.setBounds(x, 0, width, h);
               x += width;
            }
         }
         else {
            int y = 0;
            for (int i=0; i<components.size() ; i++) {
               Component c = components.get(i);
               double weight = weights.get(i);
               int height= (int)(h*weight);
               if (weight==0d)
                  height = (int)(h - h*sum);
               
               c.setBounds(0, y, w, height);
               y += height;
            }
         }
      }
   }

   public void addLayoutComponent(Component comp, Object constraints) {
      if (constraints instanceof Double) {
         double val = (Double) constraints;
         sum = 0;
         for (Double d : weights) {
            sum += d;
         }
         if (sum + val > 1) {
            throw new IllegalArgumentException(
               String.format("Not enough space left. Available %.1f%% , requested %.1f%%", (1-sum)*100, val*100));
         }
         components.add(comp);
         weights.add(val);
         sum += val;
      } 
      else if (constraints == null) {
         if (weights.contains(0d)) {
            throw new IllegalArgumentException("Component weight zero already existing");
         }
         else {
            this.addLayoutComponent(comp, 0d);
         }
      } 
      else {
         throw new IllegalArgumentException("Only double values supported");
      }

   }

   public Dimension maximumLayoutSize(Container target) {
      return this.preferredLayoutSize(target);
   }

   public float getLayoutAlignmentX(Container target) {
      return 0;
   }

   public float getLayoutAlignmentY(Container target) {
      return 0;
   }

   public void addLayoutComponent(String name, Component comp) {
      throw new IllegalArgumentException(
         "add(String, Component) ist not supported. Use add(Component, Object) or just add(Component) instead!");
   }

   public void invalidateLayout(Container target) {}

   public void removeLayoutComponent(Component comp) {}
}

_Michael 05.08.2013, 09:59