java swing изменяет размер - PullRequest
2 голосов
/ 20 февраля 2010

Я пишу библиотеку, в которой меня передают в контейнере (обычно JPanel)

и имеют спецификацию xml для различных элементов управления, их расположения, размера и других атрибутов. Я должен создать эти элементы управления во время выполнения и добавить его в компонент. Какой хороший способ справиться с изменением размера родительского контейнера?

1 Ответ

2 голосов
/ 21 февраля 2010

Если в XML указаны абсолютные местоположения, то, вероятно, нет способа элегантно изменить размеры компонентов. Вы можете создать пользовательский LayoutManager, который будет масштабировать их линейно, но для большинства компонентов это будет выглядеть плохо.

РЕДАКТИРОВАТЬ: Вот версия, которая может быть полезна:

public class LinearScaleLayout {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Linear Scale Layout Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(100, 100, 200, 200);

        JPanel scalePanel = new JPanel(new LinearScaleLayoutManager());
        scalePanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        scalePanel.add(new JTextField(), new Rectangle2D.Double(0, 0, 1, 0.2));
        scalePanel.add(new JScrollPane(new JEditorPane()), new Rectangle2D.Double(0, 0.25, 0.45, 0.75));
        scalePanel.add(new JSlider(), new Rectangle2D.Double(0.55, 0.25, 0.45, 0.75));

        frame.getContentPane().add(scalePanel);
        frame.setVisible(true);
    }

    private static class LinearScaleLayoutManager implements LayoutManager2 {
        private final HashMap<Component, Rectangle2D> rectMap = new HashMap<Component, Rectangle2D>();

        @Override
        public void layoutContainer(Container parent) {
            synchronized (parent.getTreeLock()) {
                Insets insets = parent.getInsets();
                int clientWidth = parent.getWidth() - insets.left - insets.right;
                int clientHeight = parent.getHeight() - insets.top - insets.bottom;
                if (clientWidth > 0 && clientHeight > 0) {
                    for (Component component : parent.getComponents()) {
                        Rectangle2D rect = rectMap.get(component);
                        if (rect != null) {
                            component.setBounds(new Rectangle(insets.left + (int)(rect.getX() * clientWidth), 
                                    insets.top + (int)(rect.getY() * clientHeight), (int)(rect.getWidth() * clientWidth), 
                                    (int)(rect.getHeight() * clientHeight)));
                        }
                    }
                }
            }
        }

        @Override
        public void addLayoutComponent(Component comp, Object constraints) {
            rectMap.put(comp, (Rectangle2D)constraints);
        }

        @Override
        public void removeLayoutComponent(Component comp) {
            rectMap.remove(comp);
        }

        @Override
        public Dimension minimumLayoutSize(Container parent) {
            return new Dimension(0, 0);
        }

        @Override
        public Dimension preferredLayoutSize(Container parent) {
            return new Dimension(100, 100);
        }

        @Override
        public Dimension maximumLayoutSize(Container target) {
            return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
        }

        @Override
        public void addLayoutComponent(String name, Component comp) {
        }

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

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

        @Override
        public void invalidateLayout(Container target) {
        }
    }
}
...