Установите макет с помощью JPanels

Я вообще не работал с Swing на Java. Я экспериментирую с этим. Я хочу сделать макет набора, размер которого нельзя изменить. Я видел много вещей, предлагающих использовать Layout managers для добавления нескольких JPanels в JFrame.

Тем не менее, все руководства, которые я видел с участием менеджеров компоновки, говорят, что это позволяет пользователю изменять размер экрана. Макет, который я хочу, имеет прямоугольник, идущий по левой стороне, тонкий прямоугольник, идущий по низу, и третий прямоугольник, занимающий остальную часть пространства. Я пытаюсь использовать абсолютный макет, но он просто не хочет работать для меня.

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class Test extends JFrame {

    public Test() {
        JPanel rect1 = new JPanel();
        rect1.setBounds(101, 650, 900, 50);
        rect1.setBackground(Color.RED);
        getContentPane().add(rect1);

        JPanel rect2 = new JPanel();
        rect2.setBounds(0, 650, 100, 1000);
        rect2.setBackground(Color.BLUE);
        getContentPane().add(rect2);

        JPanel rect3 = new JPanel();
        rect3.setBounds(101, 700, 900, 950);
        rect3.setBackground(Color.GREEN);
        getContentPane().add(rect3);

       setTitle("TEST");
       setSize(1000, 700);

       setLocationRelativeTo(null);
       setDefaultCloseOperation(EXIT_ON_CLOSE);        
    }


    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                Test ex = new Test();
                ex.setVisible(true);
            }
        });
    }
}

Может ли кто-нибудь помочь мне правильно сделать три Jpanel в Jframe в этом макете (все с разными цветами)?


person user2307421    schedule 31.10.2013    source источник


Ответы (5)


Возможно, вы сможете добиться того же, используя BorderLayout в качестве основы или даже GridBagLayout.

Основная часть, которую вам не хватает, это тот факт, что менеджеры компоновки используют (или могут использовать в зависимости от менеджера компоновки) предпочтительный/минимальный/максимальный размер компонента.

По сути, вы должны определить пользовательский компонент (начиная с чего-то вроде JPanel), переопределить его метод getPreferredSize и вернуть требуемое значение. В зависимости от менеджера компоновки вам также может понадобиться переопределить методы getMaximumSize и getMinimumSize.

Например...

По сути, это показывает размер «по умолчанию» и то, что происходит при изменении размера экрана...

введите здесь описание изображениявведите здесь описание изображения

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class FixedSizeLayout {

    public static void main(String[] args) {
        new FixedSizeLayout();
    }

    public FixedSizeLayout() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;

            add(new ContentPane(), gbc);
            gbc.gridx++;
            add(new LeftPane(), gbc);
            gbc.gridwidth = 2;
            gbc.gridx = 0;
            gbc.gridy = 1;
            add(new BottomPane(), gbc);

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

    public class ContentPane extends JPanel {

        public ContentPane() {
            setBackground(Color.GREEN);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(150, 150);
        }

        @Override
        public Dimension getMinimumSize() {
            return getPreferredSize();
        }

        @Override
        public Dimension getMaximumSize() {
            return getPreferredSize();
        }

    }

    public class BottomPane extends JPanel {

        public BottomPane() {
            setBackground(Color.RED);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 50);
        }

        @Override
        public Dimension getMinimumSize() {
            return getPreferredSize();
        }

        @Override
        public Dimension getMaximumSize() {
            return getPreferredSize();
        }

    }

    public class LeftPane extends JPanel {

        public LeftPane() {
            setBackground(Color.BLUE);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(50, 150);
        }

        @Override
        public Dimension getMinimumSize() {
            return getPreferredSize();
        }

        @Override
        public Dimension getMaximumSize() {
            return getPreferredSize();
        }

    }
}

Теперь, если хотите, вы можете сделать экран неизменяемым, но мне, например, вы не понравитесь. Я предпочитаю использовать возможности менеджеров компоновки и позволять пользователям принимать решения о том, как они хотят просматривать контент... где я могу... но это только я (мне не нравятся неизменяемые размеры окон, за исключением случай некоторых диалогов)

person MadProgrammer    schedule 31.10.2013
comment
ответь мне на 1 вопрос. Когда ты спишь ? - person Sage; 31.10.2013
comment
Теперь мне действительно грустно из-за того, что я не могу опубликовать вопрос так, чтобы я мог проголосовать и принять ответ. :П. В любом случае вызов принят. :| :)) - person Sage; 31.10.2013
comment
@sage Продолжайте давать качественные ответы такими, какие вы есть;) - person MadProgrammer; 31.10.2013

Вы можете использовать setResizable(). Пожалуйста, обратитесь к приведенному ниже фрагменту кода.

   setResizable(false); // this will not allow resizing
   setLocationRelativeTo(null);
   setDefaultCloseOperation(EXIT_ON_CLOSE);  
person Dark Knight    schedule 31.10.2013

AbsoluteLayout никуда не годится. Не делай этого. Вероятно, вы ищете BorderLayout. Подробности см. в руководстве: Как использовать BorderLayout. Если вы не хотите, чтобы ваш JFrame мог изменять размер, используйте на нем frame.setResizable(false);.

person Sage    schedule 31.10.2013

Просто используйте простой BorderLayout, и он автоматически изменит размер:

JPanel panel = new JPanel(new BorderLayout());
panel.add(greenPanel, BorderLayout.CENTER);
panel.add(redPanel, BorderLayout.SOUTH);
panel.add(bluePanel, BorderLayout.EAST);
person Community    schedule 02.01.2019

Вы можете использовать MigLayout и заменить BorderLayout.CENTER на «центр док-станции»:

JPanel panel = new JPanel(new MigLayout(" insets 0"));
panel.add(greenPanel, "dock center");
panel.add(redPanel, "dock south");
panel.add(bluePanel, "dock east");

Подробнее о MigLayout читайте здесь: http://www.miglayout.com/QuickStart.pdf

person Community    schedule 02.01.2019