All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.jaxx.widgets.extra.GridFlowLayout Maven / Gradle / Ivy

Go to download

Widgets graphiques utiles pour tous les développements (pour le moment sans lien avec JAXX).

There is a newer version: 3.0-alpha-17
Show newest version
/*
 * #%L
 * JAXX :: Extra Widgets
 * %%
 * Copyright (C) 2004 - 2017 CodeLutin
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */
 
 /* *
 * GridFlowLayout.java
 *
 * Created: Wed May  8 2002
 *
 * @author POUSSIN Benjamin 
 * Copyright Code Lutin
 * @version $Revision$
 *
 * Mise a jour: $Date$
 * par : $Author$
 */

package org.nuiton.jaxx.widgets.extra;

import javax.swing.JViewport;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager2;
import java.util.HashMap;
import java.util.HashSet;

/**
 * Ce layout place les composants de gauche à droite ou de droite à gauche selon
 * la valeur de {@link java.awt.Component#getComponentOrientation}. Si un
 * composant n'a pas assez de place pour se mettre sur la ligne courant, il est
 * mis sur la ligne suivante et les composants sont redimensionnés pour prendre
 * le maximum de place disponible sur la ligne. Si le container est dans un
 * {@link javax.swing.JViewport} (ou {@link javax.swing.JScrollPane}), ce layout
 * essai de ne jamais faire apparaitre le ScrollBar horizontal.
 *
 * 

* Tous les composants ont la même taille. */ public class GridFlowLayout implements LayoutManager2 { // GridFlowLayout protected final java.util.Map positions = new HashMap<>(); int hgap; int vgap; /** * GridFlowLayout constructor make a GridFlowLayout with default value (1) * for gap */ public GridFlowLayout() { this(1, 1); } /** * GridFlowLayout constructor * * @param hgap the horizontal gap between two components * @param vgap the vertical gap between two components */ public GridFlowLayout(int hgap, int vgap) { this.hgap = hgap; this.vgap = vgap; } // //////////////////////////////////////////////////////////////////// /** * Gets the horizontal gap between components. * * @return the horizontal gap between components * @see #setHgap */ public int getHgap() { return hgap; } /** * Sets the horizontal gap between components. * * @param hgap the horizontal gap between components * @see #getHgap */ public void setHgap(int hgap) { this.hgap = hgap; } /** * Gets the vertical gap between components. * * @return the vertical gap between components * @see #setVgap */ public int getVgap() { return vgap; } /** * Sets the vertical gap between components. * * @param vgap the vertical gap between components * @see #getVgap */ public void setVgap(int vgap) { this.vgap = vgap; } // //////////////////////////////////////////////////////////////////// /** * Method addLayoutComponent * * @param comp the component to add * @param constraints a constraint which is a Number (position) */ @Override public void addLayoutComponent(Component comp, Object constraints) { if (constraints instanceof Number) { positions.put(comp, constraints); } } /** * Method setConstraints * * @param comp the compoenent * @param constraints */ public void setConstraints(Component comp, Number constraints) { positions.put(comp, constraints); } /** * Method getConstraints * * @param comp * @return a number that corresponding to the constraint */ public Number getConstraints(Component comp) { return (Number) positions.get(comp); } /** * Method getLayoutAlignmentX * * @param target * @return the X layout alignement */ @Override public float getLayoutAlignmentX(Container target) { return 0.5f; } /** * Method getLayoutAlignmentY * * @param target * @return the Y layout alignement */ @Override public float getLayoutAlignmentY(Container target) { return 0.5f; } /** * Method invalidateLayout * * @param target */ @Override public void invalidateLayout(Container target) { } /** * Method addLayoutComponent * * @param name * @param comp */ @Override public void addLayoutComponent(String name, Component comp) { } /** * Method minimumLayoutSize * * @param parent * @return the minimum dimension of the layout */ @Override public Dimension minimumLayoutSize(Container parent) { synchronized (parent.getTreeLock()) { return getMinWidthHeight(parent); } } /** * Method preferredLayoutSize * * @param parent * @return the preferred dimension of the layout */ @Override public Dimension preferredLayoutSize(Container parent) { synchronized (parent.getTreeLock()) { Dimension result = getMaxWidthHeight(parent); Insets insets = parent.getInsets(); int nbChild = getComponentVisibleCount(parent); int nbColumn = (int) Math.round(Math.sqrt(nbChild)); // si un de nom parent est un JViewPort ou dit que l'on // peut etre plus petit que prevu pour eviter le scroll vertical Container container = parent; while (container != null && container.getWidth() != 0) { if (container instanceof JViewport) { nbColumn = (container.getWidth() - insets.left - insets.right) / ((int) result.getWidth() + 2 * hgap); break; } container = container.getParent(); } if (nbColumn == 0) { nbColumn++; } int nbRow = (int) Math.ceil((double) nbChild / (double) nbColumn); result.width *= nbColumn; result.height *= nbRow; result.width += hgap * 2 * nbColumn; result.height += vgap * 2 * nbRow; result.width += insets.left + insets.right; result.height += insets.top + insets.bottom; return result; } } /** * Method maximumLayoutSize * * @param target * @return the max dimension of the layout */ @Override public Dimension maximumLayoutSize(Container target) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } /** * Method removeLayoutComponent * * @param comp */ @Override public void removeLayoutComponent(Component comp) { positions.remove(comp); } /** * Method layoutContainer * * @param parent */ @Override public void layoutContainer(Container parent) { synchronized (parent.getTreeLock()) { Component components[] = parent.getComponents(); if (components.length == 0) { return; } // on met les composants dans l'ordre demande par l'utilisateur. components = computeOrder(components); Dimension max = getMaxWidthHeight(parent); int w = (int) max.getWidth(); int h = (int) max.getHeight(); Insets insets = parent.getInsets(); int parentWidth = parent.getWidth(); boolean ltr = parent.getComponentOrientation().isLeftToRight(); // recalcul de la largeur et du nombre de colonne int nbColumn = (parentWidth - insets.left - insets.right) / (w + 2 * hgap); if (nbColumn == 0) { nbColumn++; } w = (parentWidth - insets.left - insets.right) / nbColumn; w -= 2 * hgap; // nombre a soustraire pour commencer les lignes a gauche // ou a droite int ltrNb = 0; int horizontalMargin = insets.left; int verticalMargin = insets.top; if (!ltr) { ltrNb = nbColumn - 1; horizontalMargin = insets.right; } int count = 0; for (Component component : components) { if (component.isVisible()) { int column = count % nbColumn; int row = count / nbColumn; component.setBounds( /* on calcul la position */Math.abs(ltrNb - column) * w /* on ajoute la marge */ + horizontalMargin /* on ajoute les intervales */ + (2 * column + 1) * hgap, /* on calcul la position */row * h /* on ajoute la marge */ + verticalMargin /* on ajoute les intervales */ + (2 * row + 1) * vgap, w, h); count++; } } } } // //////////////////////////////////////////////////////////////////// /** * Method getComponentVisibleCount * * @param parent * @return an integer that corresponding to the number of visible components */ protected int getComponentVisibleCount(Container parent) { int result = 0; Component components[] = parent.getComponents(); for (Component component : components) { if (component.isVisible()) { result++; } } return result; } /** * Method getMaxWidthHeight * * @param parent * @return the max size */ protected Dimension getMaxWidthHeight(Container parent) { Component components[] = parent.getComponents(); Dimension result = new Dimension(0, 0); for (Component component : components) { if (component.isVisible()) { Dimension d = component.getPreferredSize(); result.width = Math.max(result.width, d.width); result.height = Math.max(result.height, d.height); } } return result; } /** * Method getMinWidthHeight * * @param parent * @return the dimension of this layout */ protected Dimension getMinWidthHeight(Container parent) { Component components[] = parent.getComponents(); Dimension result = new Dimension(0, 0); for (Component component : components) { if (component.isVisible()) { Dimension d = component.getMinimumSize(); result.width = Math.max(result.width, d.width); result.height = Math.max(result.height, d.height); } } return result; } /** * Method [] * * @param components * @return une tablean de composants contenus dans le layout */ public Component[] computeOrder(Component[] components) { Component[] result = new Component[components.length]; // contient les composants dont la contrainte n'est pas bonne // et que l'on place comme s'il n'avait pas de contraint. HashSet inWait = new HashSet<>(); // on commence par mettre les composants dont on connait la position for (Component comp : positions.keySet()) { Number pos = (Number) positions.get(comp); if (pos != null && -1 < pos.intValue() && pos.intValue() < result.length) { result[pos.intValue()] = comp; } else { inWait.add(comp); } } // on place les autres composants int j = 0; for (Component component : components) { // si la contrainte etait fausse, ou qu'il n'y en avait pas if (inWait.contains(component) || !positions.containsKey(component)) { // on cherche la prochaine place vide while (result[j] != null) { j++; } // pour mettre le composant result[j] = component; } } return result; } // //////////////////////////////////////////////////////////////////// public static void main(String[] args) { javax.swing.JPanel panel = new javax.swing.JPanel(new GridFlowLayout( 10, 5)); for (int i = 0; i < 10; i++) { panel.add(new javax.swing.JButton("label " + i), new Integer(i + 3)); } javax.swing.JFrame frame = new javax.swing.JFrame("Test"); frame.getContentPane().add(new javax.swing.JScrollPane(panel)); frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } } // GridFlowLayout





© 2015 - 2024 Weber Informatics LLC | Privacy Policy