Изменение размера JFrame перемещает разделитель JSplitPane

Я использую два JSplitPanes для отображения некоторой информации. Один ориентирован с горизонтальным разделителем, другой с вертикальным разделителем. Следующая проблема относится к обоим JSplitPanes.

Когда я изменяю размер основного JFrame моего приложения, размер JSplitPanes также изменяется, поскольку они должны занимать определенный процент экрана (все JPanels настраиваются на изменение размера JFrame, поведение задается параметрами ширины и высоты MigLayout).

Расположение разделителя важно и должно соответствовать размеру JSplitPane. Для этого я использую setResizeWeight() и setDividerLocation().

Основная проблема заключается в том, что при изменении размера JFrame делитель не остается на уровне 0,0/0%, а вместо этого перемещается на ~ 5-10%:

Предварительное изменение размера-----> После изменения размера

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

Может ли кто-нибудь помочь мне с этой проблемой? Я реализовал ComponentAdapter, но не сохранил расположение разделителя в переменной или Preferences XML-ключе, я не могу восстановить расположение разделителя на componentResized().

Пример кода:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;

import net.miginfocom.swing.MigLayout;


public class JSplitPaneTest {

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setMinimumSize(new Dimension(500, 500));

        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new MigLayout());

        JPanel panel1 = new JPanel();
        panel1.setBackground(Color.RED);

        JPanel panel2 = new JPanel();
        panel1.setBackground(Color.GREEN);

        final JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
                panel1, panel2);
        splitPane.setResizeWeight(0.5);
        splitPane.setOpaque(false);
        splitPane.setOneTouchExpandable(true); // does not work on Linux :(
        splitPane.setBorder(null);

        mainPanel.add(splitPane, "w 100%, h 90%, wrap");

        JButton button = new JButton("Set to 0");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                splitPane.setDividerLocation(0.0);
            }
        });

        mainPanel.add(button, "span");

        frame.add(mainPanel);
        frame.setVisible(true);
    }
}

person ChrisK    schedule 05.02.2015    source источник
comment
для лучшей справки скорее опубликуйте SSCCE/MCVE, короткий, исполняемый, компилируемый   -  person mKorbel    schedule 05.02.2015
comment
Я добавил пример кода. setResizeWeight() меняет поведение. Но делитель никогда не остается на 0.   -  person ChrisK    schedule 05.02.2015


Ответы (1)


Я работаю над тем же проектом, что и @ChrisK, и сегодня взглянул на него. Я считаю, что исправил эту проблему, хотя я не подтвердил конкретный симптом, вызванный изменением размера окна (поскольку мы перешли к jSplitPane со статическим размером, и изменение размера окна больше не меняет положение разделителя). Однако у нас была другая проблема, которая, как я полагаю, была вызвана той же основной проблемой: после перемещения разделителя из позиции 0 больше нельзя было вручную перетащить разделитель обратно в позицию 0. Оказалось, что это связано с минимальным размером jPanel. , который никогда не устанавливался явно. Оказалось, что метод leftComponent.getMinimumSize() возвращал (случайно/произвольно?) 32, что оказалось крайней левой позицией пикселя, мимо которой нельзя было перетащить разделитель.

Поэтому я сделал вызов:

panel1.setMinimumSize(new Dimension(0,0));

чтобы разделитель можно было перетащить полностью влево/вверх и:

panel2.setMinimumSize(new Dimension(0,0));

чтобы можно было перетащить разделитель вправо/вниз.

Я считаю, что эти значения мешали положению разделителя при изменении размера компонента. Я так и не смог понять, почему были установлены, казалось бы, произвольные минимальные значения (32x47) для размера панели. Эти значения возвращаются функцией getMinimumSize сразу после построения панелей. Если кто-нибудь знает, как они рассчитываются, это может помочь составить более полную картину происходящего. Если это помогает, ширина/высота разделенных панелей в измерении разделителя-перетаскивания устанавливается статически на 180.

person hepcat72    schedule 03.03.2016
comment
Еще более года назад, когда я провел некоторое исследование по этому вопросу, я увидел java-swi">этот пост. Это может быть интересное чтение. - person ChrisK; 05.03.2016
comment
Вы должны сообщить @kleopatra об этой проблеме, так как моя работа в настоящее время является единственным решением, о котором мы знаем на данный момент. Я признаю, что это может быть нецелесообразно, хотя я не так хорошо знаком с Swing, как вы, но я думал, что вы считаете такое поведение разделителя разделенной панели ошибкой, и если это так, то, пока это не будет исправлено, кажется, все, что вы можете сделать, это обойти это. - person hepcat72; 06.03.2016
comment
Как вы думаете, мы должны переопределить getminimumsize вместо вызова минимального размера, как во втором ответе? - person hepcat72; 06.03.2016
comment
Да, я думаю, что переопределить это предпочтительнее. Я подумал, что это ошибка, потому что это также происходит в коротком независимом примере, который я опубликовал. Или, может быть, я что-то упустил в MigLayout. - person ChrisK; 07.03.2016