XY Layout JAVA

前端 未结 4 1171
刺人心
刺人心 2021-01-07 03:46

is there any sort of XY-Layout to Java?

So I can set a Button at the X and Y cordinate and that it is suppose to be that big etc.... Because this border layout and

相关标签:
4条回答
  • 2021-01-07 04:31

    The reason components resize is so stuff looks nice whatever size the window is, so Swing discourages straight X-Y position. You might want to have a look at GroupLayout http://java.sun.com/docs/books/tutorial/uiswing/layout/group.html which is designed for GUI builders, and the page mentioned above describes using invisible components to absorb the stretches. eg:layout.setAutoCreateGaps(true);

    SpringLayout might also be useful - see the visual guide

    If you really want X and Y then set the layout manager to null, and use setLocation() or setBounds(). I REALLY REALLY wouldn't recommend this, but it does work. Have a read of this tutorial

    0 讨论(0)
  • 2021-01-07 04:31

    This doesn't answer your specific question, but as well as agreeing with the other comments, have a look at MiG Layout. I have been equally frustrated with layouts as a Swing newbie, but this has helped a lot.

    0 讨论(0)
  • 2021-01-07 04:45

    When setting the container's layout to null (no LayoutManager), you can set the component's bounds individually with component.setBounds(x,y,w,h).

    Fixed layouts are in 99% of all cases bad UI design (if your labels, for example, don't get their preferred size you run into mayor problems when your application supports multiple languages), so my advice for you is to rather write a specialized layout manager for your specific needs.

    Writing your custom layout manager is quite easy, all you have to do is to be able to calculate the preferred size for a container with given components and your layout, and to do the layout by setting the (calculated) bounds of your components. I got rid of the GridBagLayout and started coding my own layouts long ago, and layouting has never been easier.

    Here's an example of a custom layout, that layouts pairs of key and value components:

    public class KeyValueLayout implements LayoutManager {
    
        public static enum KeyAlignment {
            LEFT, RIGHT;
        }
    
        private KeyAlignment keyAlignment = KeyAlignment.LEFT;
    
        private int hgap;
    
        private int vgap;
    
        public KeyValueLayout () {
            this(KeyAlignment.LEFT);
        }
    
        public KeyValueLayout (KeyAlignment keyAlignment) {
            this(keyAlignment, 5, 5);
        }
    
        public KeyValueLayout (int hgap, int vgap) {
            this(KeyAlignment.LEFT, hgap, vgap);
        }
    
        public KeyValueLayout (KeyAlignment keyAlignment, int hgap, int vgap) {
    
            this.keyAlignment = keyAlignment != null ? keyAlignment : KeyAlignment.LEFT;
            this.hgap = hgap;
            this.vgap = vgap;
        }
    
        public void addLayoutComponent (String name, Component comp) {
        }
    
        public void addLayoutComponent (Component comp, Object constraints) {
        }
    
        public void removeLayoutComponent (Component comp) {
        }
    
        public void layoutContainer (Container parent) {
            Rectangle canvas = getLayoutCanvas(parent);
            int ypos = canvas.y;
            int preferredKeyWidth = getPreferredKeyWidth(parent);
    
            for (Iterator<Component> iter = new ComponentIterator(parent); iter.hasNext();) {
                Component key = (Component) iter.next();
                Component value = iter.hasNext() ? (Component) iter.next() : null;
                int xpos = canvas.x;
                int preferredHeight = Math.max(key.getPreferredSize().height, value != null ? value.getPreferredSize().height : 0);
    
                if (keyAlignment == KeyAlignment.LEFT)
                    key.setBounds(xpos, ypos, key.getPreferredSize().width, key.getPreferredSize().height);
                else
                    key.setBounds(xpos + preferredKeyWidth - key.getPreferredSize().width, ypos, key.getPreferredSize().width,
                        key.getPreferredSize().height);
    
                xpos += preferredKeyWidth + hgap;
                if (value != null)
                    value.setBounds(xpos, ypos, canvas.x + canvas.width - xpos, preferredHeight);
                ypos += preferredHeight + vgap;
            }
        }
    
        public Dimension minimumLayoutSize (Container parent) {
            int preferredKeyWidth = getPreferredKeyWidth(parent);
            int minimumValueWidth = 0;
            int minimumHeight = 0;
            int lines = 0;
            for (Iterator<Component> iter = new ComponentIterator(parent); iter.hasNext();) {
                lines++;
                Component key = (Component) iter.next();
                Component value = iter.hasNext() ? (Component) iter.next() : null;
                minimumHeight += Math.max(key.getPreferredSize().height, value != null ? value.getMinimumSize().height : 0);
                minimumValueWidth = Math.max(minimumValueWidth, value != null ? value.getMinimumSize().width : 0);
            }
    
            Insets insets = parent.getInsets();
            int minimumWidth = insets.left + preferredKeyWidth + hgap + minimumValueWidth + insets.right;
            minimumHeight += insets.top + insets.bottom;
            if (lines > 0)
                minimumHeight += (lines - 1) * vgap;
    
            return new Dimension(minimumWidth, minimumHeight);
        }
    
        public Dimension preferredLayoutSize (Container parent) {
            int preferredKeyWidth = getPreferredKeyWidth(parent);
            int preferredValueWidth = 0;
            int preferredHeight = 0;
            int lines = 0;
            for (Iterator<Component> iter = new ComponentIterator(parent); iter.hasNext();) {
                lines++;
                Component key = (Component) iter.next();
                Component value = iter.hasNext() ? (Component) iter.next() : null;
    
                preferredHeight += Math.max(key.getPreferredSize().height, value != null ? value.getPreferredSize().height : 0);
                preferredValueWidth = Math.max(preferredValueWidth, value != null ? value.getPreferredSize().width : 0);
            }
    
            Insets insets = parent.getInsets();
            int preferredWidth = insets.left + preferredKeyWidth + hgap + preferredValueWidth + insets.right;
            preferredHeight += insets.top + insets.bottom;
            if (lines > 0)
                preferredHeight += (lines - 1) * vgap;
    
            return new Dimension(preferredWidth, preferredHeight);
        }
    
        public Dimension maximumLayoutSize (Container target) {
            return preferredLayoutSize(target);
        }
    
        private int getPreferredKeyWidth (Container parent) {
            int preferredWidth = 0;
            for (Iterator<Component> iter = new ComponentIterator(parent); iter.hasNext();) {
                Component key = (Component) iter.next();
                if (iter.hasNext())
                    iter.next();
    
                preferredWidth = Math.max(preferredWidth, key.getPreferredSize().width);
            }
    
            return preferredWidth;
        }
    
        private Rectangle getLayoutCanvas (Container parent) {
            Insets insets = parent.getInsets();
            int x = insets.left;
            int y = insets.top;
    
            int width = parent.getSize().width - insets.left - insets.right;
            int height = parent.getSize().height - insets.top - insets.bottom;
    
            return new Rectangle(x, y, width, height);
        }
    
        private class ComponentIterator implements Iterator<Component> {
    
            private Container container;
    
            private int index = 0;
    
            public ComponentIterator (Container container) {
                this.container = container;
            }
    
            public boolean hasNext () {
                return index < container.getComponentCount();
            }
    
            public Component next () {
                return container.getComponent(index++);
            }
    
            public void remove () {
            }
        }
    }
    

    Just set the layout and add alternatingly labels and value components. It's easy to use, especially compared to GridBagLayout or nested panels with custom layouts.

    0 讨论(0)
  • 2021-01-07 04:47

    If you really want to do this, use

    setLayout(null);
    

    on the component you're putting things into, then use

    setBounds(x, y, width, height);
    

    to set the absolute coordinates of the elements. Example:

    setLayout(null);
    JButton myButton = new JButton("Do Stuff");
    add(myButton);
    myButton.setBounds(30, 30, 100, 30);
    

    However, the resulting GUI will look non-standard, won't be resizable, and if it's of any complexity, will be a pain to maintain.

    I know that layouting is frustrating, but in the end you will be better off using a combination of BorderLayouts and FlowLayouts, orGridBagLayout - or an IDE interface builder like Eclipse's or Netbeans'.

    0 讨论(0)
提交回复
热议问题