7
votes

LayoutOutManager approprié pour des composants redimensionnables

Il y a parfois parfois, j'ai lu cette article qui montre un moyen d'implémenter des composants révisibles de la souris en swing.

L'auteur utilise un null LayoutAutManager afin de permettre un positionnement absolu des composants. Je sais qu'une disposition nulle ne devrait jamais être utilisée, alors ma question est la suivante:

Y a-t-il déjà mis en œuvre layoutAutManager qui permettent le positionnement absolu du composant ou je dois la mettre en œuvre le mien?


3 commentaires

Essayez-vous de faire des composants résidu à la souris? Si oui, pourquoi?


@Andrew Thompson: J'ai une sorte de toile où l'utilisateur doit pouvoir insérer des composants de formes différentes, le positionnement et les redimensionnement. Si vous connaissez une meilleure façon de le faire sans permettre à des composants d'être de la souris sévencable, mettez-moi dans la bonne direction. (Je préférerais utiliser des composants au lieu de dessiner des formes dans un jPanel car je peux utiliser des événements de souris pour les déplacer et les redimensionner)


Pour la plupart des guies complexes, je plaçant avec la grillebaglaout, mais où je mets à la première ligne (matrice horizontale) 50-80 petits jlabels, alors je ne dois jamais résoudre l'absorposition, puis je mets jcomponent à la colonne de rangée et pour la taille de la hauteur / du poids à nouveau avec des nombres de colonne et de rangée,


4 Réponses :


0
votes

La question est quelque peu vague, alors je risquais de manquer complètement le point. Je suppose que vous recherchez une mise en page qui vous permettra d'utiliser un positionnement absolu, mais vous permettra toujours de redimensionner le composant et d'utiliser tous les espaces disponibles.

Si vous êtes à la mode, j'ai eu du succès avec Miglayout ( http://www.miglayout.com/ ) et tablier (qui est moins absolu mais très facile à utiliser - http://java.sun.com/products/jfc/tsc/articles/tablelayout/ )

Si vous utilisez un concepteur de formulaire, l'utilisation de Grouplayout peut être un bon choix, mais que vous ne voulez pas la conduire à la main. Voir cette question: grouplayout: Est-ce que cela vaut la peine d'apprendre?


2 commentaires

Merci pour la réponse mais je cherche quelque chose de différent. Regardez le lien que j'ai posté. J'ai besoin de des composants de positionnement absolus et de chanter de manière dynamique leurs limites. Je l'ai déjà mis en œuvre de manière similaire à l'article lié, mais je sais que l'utilisation d'un gestionnaire de mise en page NULL est découragé. Je me demandais donc s'il y a un gestionnaire de mise en page qui permet de telles opérations ou que je dois la mettre en œuvre.


Désolé, j'ai fait trop d'hypothèses et j'ai répondu aux mauvaises questions ... J'ai ajouté une nouvelle réponse.



1
votes

Je suppose que cela dépendrait des détails de la façon dont vous vouliez qu'il se comporte.

La raison principale Le gestionnaire de mise en page NULL est découragé est dû au fait que les interfaces intégrées à l'aide de ceux qui ne peuvent être utilisées que dans la taille qu'ils ont été conçues - vous ne pouvez pas redimensionner l'interface utilisateur. Si cela vous convient, utilisez-le.

Une autre option que je connaisse est l'absolutelayout que NetBeans est distribué avec. Vous pouvez obtenir plus d'informations ici: http: / /www.java-tips.org/other-api-tips/netbeans/can-i-distribute-absolutelayout-with-my-applica.html . Je pense que cela pourrait être exactement ce que vous recherchez, mais comme vous pouvez le constater à partir de ce lien, ils recommandent plutôt d'utiliser une mise en page nulle ... Je ne pense pas que cela fait une grande partie de la différence.

Si vous devez pouvoir permettre aux utilisateurs de définir la manière dont les composants redimensionneront également, vous finirez par créer quelque chose comme le concepteur de formulaire MAISSE NETBEANS, qui est probablement trop amusant et ne me frappe pas autant de plaisir :)


0 commentaires

4
votes

1 commentaires

+1: Merci beaucoup. Je pense que les composants de redimensionnement et les fenêtres en mouvement sont exactement ce que je cherchais!



3
votes

Un gestionnaire de mise en page fait vraiment 3 choses:

  1. Définissez l'emplacement d'un composant. Depuis que vous avez besoin de la possibilité de faire glisser le composant, vous ne voudrez pas que votre gestionnaire de mise en page fasse cela. P> LI>

  2. Définissez la taille d'un composant. Depuis que vous avez besoin de la possibilité de redimensionner le composant, vous ne voudrez pas faire cela. Cependant, vous voudrez peut-être donner à la composante une taille par défaut en fonction de la taille de la préférence des composants. De cette façon, vous n'avez pas besoin de spécifier la taille lorsque vous créez le composant. P> LI>

  3. Déterminez la taille préférée du panneau parent en fonction des composants ajoutés à celui-ci. Cela permettra aux vitres de défilement fonctionner correctement car les barres de défilement peuvent être ajoutées / supprimées selon les besoins. Vous devez donc déterminer le comportement de la façon dont la glissant doit fonctionner. C'est-à-dire que vous êtes autorisé à faire glisser le composant en dehors des limites actuelles du panneau. Si de sorte que la taille préférée du panneau devrait augmenter automatiquement. P> li> ol>

    existe-t-il déjà implémenté layoutManager qui permettent le positionnement absolu de composant p> BlockQuote>

    Je joue avec un gestionnaire de mise en page proche de vos besoins. Il a été conçu pour être utilisé avec la classe ComponentMover à partir du Windows en mouvement lien fourni par TrashGOD. P>

    Voici mon code de test pour cette classe: P>

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.border.*;
    
    /**
     */
    public class DragLayout implements LayoutManager, java.io.Serializable
    {
        public DragLayout()
        {
        }
    
        /**
         * Adds the specified component with the specified name to the layout.
         * @param name the name of the component
         * @param comp the component to be added
         */
        @Override
        public void addLayoutComponent(String name, Component comp) {}
    
    
        /**
         * Removes the specified component from the layout.
         *
         * @param comp the component to be removed
         */
        @Override
        public void removeLayoutComponent(Component component)
        {
        }
    
        /**
         *  Determine the minimum size on the Container
         *
         *  @param   target   the container in which to do the layout
         *  @return  the minimum dimensions needed to lay out the
         *           subcomponents of the specified container
         */
        @Override
        public Dimension minimumLayoutSize(Container parent)
        {
            synchronized (parent.getTreeLock())
            {
                return preferredLayoutSize(parent);
            }
        }
    
        /**
         *  Determine the preferred size on the Container
         *
         *  @param   parent   the container in which to do the layout
         *  @return  the preferred dimensions to lay out the
         *           subcomponents of the specified container
         */
        @Override
        public Dimension preferredLayoutSize(Container parent)
        {
            synchronized (parent.getTreeLock())
            {
                return getLayoutSize(parent);
            }
        }
    
        /*
         *  The calculation for minimum/preferred size it the same. The only
         *  difference is the need to use the minimum or preferred size of the
         *  component in the calculation.
         *
         *  @param   parent  the container in which to do the layout
         */
        private Dimension getLayoutSize(Container parent)
        {
            Insets parentInsets = parent.getInsets();
            int x = parentInsets.left;
            int y = parentInsets.top;
            int width = 0;
            int height = 0;
    
            //  Get extreme values of the components on the container
    
            for (Component component: parent.getComponents())
            {
                if (component.isVisible())
                {
                    Point p = component.getLocation();
                    Dimension d = component.getPreferredSize();
                    x = Math.min(x, p.x);
                    y = Math.min(y, p.y);
                    width = Math.max(width, p.x + d.width);
                    height = Math.max(height, p.y + d.height);
                }
            }
    
            // Width/Height is adjusted if any component is outside left/top edge
    
            if (x < parentInsets.left)
                width += parentInsets.left - x;
    
            if (y < parentInsets.top)
                height += parentInsets.top - y;
    
            //  Adjust for insets
    
            width += parentInsets.right;
            height += parentInsets.bottom;
            Dimension d = new Dimension(width, height);
    
            return d;
    //      return new Dimension(width, height);
        }
    
        /**
         * Lays out the specified container using this layout.
         *
         * @param     target   the container in which to do the layout
         */
        @Override
        public void layoutContainer(Container parent)
        {
        synchronized (parent.getTreeLock())
        {
            Insets parentInsets = parent.getInsets();
    
            int x = parentInsets.left;
            int y = parentInsets.top;
    
            //  Get X/Y location outside the bounds of the panel
    
            for (Component component: parent.getComponents())
            {
                if (component.isVisible())
                {
                    Point location = component.getLocation();
                    x = Math.min(x, location.x);
                    y = Math.min(y, location.y);
                }
            }
    
            x = (x < parentInsets.left) ? parentInsets.left - x : 0;
            y = (y < parentInsets.top) ? parentInsets.top - y : 0;
    
            //  Set bounds of each component
    
            for (Component component: parent.getComponents())
            {
                if (component.isVisible())
                {
                    Point p = component.getLocation();
                    Dimension d = component.getPreferredSize();
    
                    component.setBounds(p.x + x, p.y + y, d.width, d.height);
                }
            }
        }}
    
        /**
         * Returns the string representation of this column layout's values.
         * @return   a string representation of this layout
         */
        public String toString()
        {
            return "["
                + getClass().getName()
                + "]";
        }
    
        public static void main( String[] args )
        {
            ComponentMover cm = new ComponentMover();
            cm.setEdgeInsets( new Insets(-100, -100, -100, -100) );
    //      cm.setEdgeInsets( new Insets(10, 10, 10, 10) );
            cm.setAutoLayout(true);
    
            JPanel panel = new JPanel( new DragLayout() );
            panel.setBorder( new MatteBorder(10, 10, 10, 10, Color.YELLOW) );
    
            createLabel(cm, panel, "North", 150, 0);
            createLabel(cm, panel, "West", 0, 100);
            createLabel(cm, panel, "East", 300, 100);
            createLabel(cm, panel, "South", 150, 200);
            createLabel(cm, panel, "Center", 150, 100);
    
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add( new JScrollPane(panel) );
            frame.pack();
            frame.setLocationRelativeTo( null );
            frame.setVisible( true );
        }
    
        public static void createLabel(ComponentMover cm, JPanel panel, String text, int x, int y)
        {
            JLabel label = new JLabel( text );
            label.setOpaque(true);
            label.setBackground( Color.ORANGE );
            label.setLocation(x, y);
            panel.add( label );
            cm.registerComponent( label );
        }
    
    }
    


2 commentaires

+1: Merci, c'est vraiment génial! Quand j'ai le temps, je refactoriserai tout mon code avec votre Compontresizer. Qu'en est-il de la licence de celui-ci? Puis-je l'utiliser à l'intérieur de l'application commerciale à sources fermée aussi?


Découvrez DIRECTION de la mise en page pour la version à jour de ce code . Le code est disponible tel quel et vous pouvez utiliser le code mais vous s'il vous plaît.