Как правильно установить минимальные размеры в Java?

для приложения GUI, которое я создаю на Java, у меня есть следующее:

  • в JFrame, имеет минимальный размер (300,200)
  • A JSplitPane, в котором лежит:
    • слева, JScrollPane (содержащий JTree) с минимальным размером (100,0) (я только хочу ограничить ширину до 200)
    • справа, JPanel с минимальным размером (200,0)

размер не дает мне никакой проблемы под следующие условия:

  • изменение размера JSplitPane полностью влево (до минимального размера JScrollPane), а затем изменение размера окна после
  • просто изменение размера окна, в определенной степени

проблема возникает, когда я перемещаю JSplitPane слишком близко вправо, после чего изменение размера окна JPanel в правой части JSplitPane не соответствует минимальной ширине, которую я установил.

Я попытался установить максимальная ширина на JScrollPane, которая, казалось, не помогала вообще.

есть ли что-то с максимальными размерами, которые я должен сделать? Или, может быть, есть способ прикрепить слушателя к одной из панелей, чтобы заставить мое желаемое поведение? В конечном счете, я просто хочу, чтобы правая панель в JSplitPane никогда не была меньше 200px.

вот пример с поведением, которое я испытываю:

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;

public class ResizeTest
{
    private JFrame frame;
    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    ResizeTest window = new ResizeTest();
                    window.frame.setVisible(true);
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
        });
    }
    public ResizeTest()
    {
        initialize();
    }
    private void initialize()
    {
        frame = new JFrame();
        frame.setMinimumSize(new Dimension(300, 200));
        frame.setBounds(100,100,450,300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new GridLayout(0, 1, 0, 0));

        JSplitPane splitPane = new JSplitPane();
        frame.getContentPane().add(splitPane);

        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setMinimumSize(new Dimension(100, 0));
        splitPane.setLeftComponent(scrollPane);

        JTree tree = new JTree();
        tree.setMinimumSize(new Dimension(100, 0));
        scrollPane.setViewportView(tree);

        JPanel panel = new JPanel();
        panel.setMinimumSize(new Dimension(200, 0));
        splitPane.setRightComponent(panel);
    }
}

обновление:

боюсь, я не полностью поймите, что нужно сделать в предлагаемых решениях, за исключением того, что setPreferred () и setMinimum/Maximum () лучше избегать.

мой вопрос в ответ на это обучение, каковы мои варианты ограничения разделителя JSplitPane вне использования этих методов? MadProgrammer упомянуто прослушивание события componentResized, но мне нужно немного больше разъяснений относительно того, почему. Я вызываю setDividerLocation () в реакция на это событие?

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

обновление 2:

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

2 ответов


во-первых, метод setMinimumSize это предложение LayoutManager API-интерфейс. Предложение, которое можно проигнорировать.

чтобы иметь возможность даже приблизиться к поддержке этого, вам нужно будет использовать что-то вроде ComponentListener и монитор componentResized событие.

лучшее решение, которое я могу придумать, это использовать LayoutManager который фактически использует минимальные и максимальные ограничения размера, что-то вроде GridBagLayout.

использовать это на панели "содержимое" и место, где вы JSplitPane на это (установка минимального и максимального размера соответственно) затем добавьте панель "содержимое" в рамку.

обновление

Извините, я, вероятно, пропустил что-то действительно очевидное, но я поставил этот маленький тест вместе, надеюсь, что у него есть некоторые идеи, которые помогают :P

public class TestFrameSize extends JFrame {

    public TestFrameSize() throws HeadlessException {

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(600, 600);
        setLocationRelativeTo(null);

        setMinimumSize(new Dimension(250, 250));

        JLabel left = new JLabel("Left");
        JLabel right = new JLabel("Right");

        Dimension pSize = new Dimension(100, 100);
        Dimension mSize = new Dimension(25, 100);

        left.setPreferredSize(pSize);
        left.setMinimumSize(mSize);
        right.setPreferredSize(pSize);
        right.setMinimumSize(mSize);

        JSplitPane pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, right);

        JPanel content = new JPanel(new GridBagLayout());
        content.add(pane);

        setLayout(new BorderLayout());
        add(content);

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        new TestFrameSize().setVisible(true);

    }
}

в этой пример предпочтительный размер содержания JSplitPane первоначально устанавливается в небольшое кратное предпочтительному размеру компонента в getPreferredSize(). Обратите внимание, что JSplitPane станет не меньше минимального размера панели, управляемого прилагаемым Jlabel.

image