Как вы можете программно установить JSplitPane, чтобы скрыть правый / нижний компонент, когда OneTouchExpandable имеет значение true? - PullRequest
4 голосов
/ 07 февраля 2012

В JSplitPane у вас есть метод setOneTouchExpandable, который предоставляет вам 2 кнопки, чтобы быстро полностью скрыть или полностью показать JSplitPane.

У меня вопрос как вы можете программно«нажмите» кнопку скрытия на JSplitPane?

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

Это работает:

import javax.swing.*;

class SplitPaneDefault {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JSplitPane sp = new JSplitPane(
                    JSplitPane.HORIZONTAL_SPLIT,
                    new JTree(),
                    new JTree());
                sp.setOneTouchExpandable(true);
                sp.setDividerLocation(0.0);
                JOptionPane.showMessageDialog(null, sp);
            }
        });
    }
}

, но замена 0.0 на 1.0 не скрывает нужный компонент.Это моя проблема!

Ответы [ 5 ]

5 голосов
/ 07 февраля 2012
import javax.swing.*;

class SplitPaneDefault {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JSplitPane sp = new JSplitPane(
                    JSplitPane.HORIZONTAL_SPLIT,
                    new JTree(),
                    new JTree());
                sp.setOneTouchExpandable(true);
                sp.setDividerLocation(0.0);
                JOptionPane.showMessageDialog(null, sp);
            }
        });
    }
}

замените 0.0 на 1.0, и вы получите мою проблему

Прочтите подробное руководство и решите проблему.

Этот методнемедленно изменяет размер разделенной панели в зависимости от ее текущего размера. Если разделенная панель не реализована правильно и на экране этот метод не будет иметь никакого эффекта ...

SplitPaneDefault

import javax.swing.*;

class SplitPaneDefault {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JSplitPane sp = new JSplitPane(
                    JSplitPane.HORIZONTAL_SPLIT,
                    new JTree(),
                    new JTree());
                sp.setOneTouchExpandable(true);
                JFrame f = new JFrame("Split Pane To Right");
                f.add(sp);
                f.pack();
                // sp now has a non-zero size!
                sp.setDividerLocation(1.0);
                f.setLocationByPlatform(true);
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setVisible(true);
            }
        });
    }
}
2 голосов
/ 01 июня 2018

Вот еще одно решение, возможно, немного грязное, но оно работает;) Я надеюсь, что код говорит сам за себя.

public class ExtOneTouchJSplitPane extends JSplitPane {
    private static final long serialVersionUID = -2320161961382260438L;

    JButton jBLeftUp;
    JButton jBRightDown;

    public ExtOneTouchJSplitPane() {
        super();
        setOneTouchExpandable(true);
        extractDividerButtons();
    }

    public ExtOneTouchJSplitPane(int newOrientation) {
        super(newOrientation);
        setOneTouchExpandable(true);
        extractDividerButtons();
    }

    public ExtOneTouchJSplitPane(int newOrientation, boolean newContinuousLayout) {
        super(newOrientation, newContinuousLayout);
        setOneTouchExpandable(true);
        extractDividerButtons();
    }

    public ExtOneTouchJSplitPane(int newOrientation, boolean newContinuousLayout, Component newLeftComponent, Component newRightComponent) {
        super(newOrientation, newContinuousLayout, newLeftComponent, newRightComponent);
        setOneTouchExpandable(true);
        extractDividerButtons();
    }

    public ExtOneTouchJSplitPane(int newOrientation, Component newLeftComponent, Component newRightComponent) {
        super(newOrientation, newLeftComponent, newRightComponent);
        setOneTouchExpandable(true);
        extractDividerButtons();
    }

    private void extractDividerButtons() {
        BasicSplitPaneUI ui = (BasicSplitPaneUI) getUI();
        jBLeftUp = (JButton) ui.getDivider().getComponent(0);
        jBRightDown = (JButton) ui.getDivider().getComponent(1);
    }

    public void oneTouchClickLeft() {
        jBLeftUp.doClick();
    }

    public void oneTouchClickRight() {
        jBRightDown.doClick();
    }

    public void oneTouchClickUp() {
        jBLeftUp.doClick();
    }

    public void oneTouchClickDown() {
        jBRightDown.doClick();
    }
}

И пример, как его использовать:

public class SplitPaneDemo extends JFrame implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new SplitPaneDemo());
    }

    ExtOneTouchJSplitPane hSplitPane;
    ExtOneTouchJSplitPane vSplitPane;

    public SplitPaneDemo() {
        createView();
    }

    public void createView() {
        setTitle("SplitPane-Demo");
        setLayout(new BorderLayout(0, 0));

        hSplitPane = new ExtOneTouchJSplitPane();
        JButton jBLeft = new JButton("<html><body> &nbsp;<br>Left Component<br> &nbsp;</body></html>");
        JButton jBRight = new JButton("<html><body> &nbsp;<br>Right Component<br> &nbsp;</body></html>");
        jBLeft.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                hSplitPane.oneTouchClickLeft();
            }
        });
        jBRight.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                hSplitPane.oneTouchClickRight();
            }
        });
        hSplitPane.setLeftComponent(jBLeft);
        hSplitPane.setRightComponent(jBRight);

        add(hSplitPane, BorderLayout.CENTER);

        vSplitPane = new ExtOneTouchJSplitPane(JSplitPane.VERTICAL_SPLIT);
        JButton jBUp = new JButton("<html><body> &nbsp;<br>Up Component<br> &nbsp;</body></html>");
        JButton jBDown = new JButton("<html><body> &nbsp;<br>Down Component<br> &nbsp;</body></html>");
        jBUp.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                vSplitPane.oneTouchClickUp();
            }
        });
        jBDown.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                vSplitPane.oneTouchClickDown();
            }
        });
        vSplitPane.setTopComponent(jBUp);
        vSplitPane.setBottomComponent(jBDown);

        add(vSplitPane, BorderLayout.SOUTH);
    }

    @Override
    public void run() {
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(400, 400);
        setVisible(true);

        hSplitPane.oneTouchClickLeft();
    }
}
2 голосов
/ 07 февраля 2012

Вы можете просто использовать это:

public void setDividerLocation(double proportionalLocation)

splitPane.setDividerLocation(0.0d);

или *. * 1004

splitPane.setDividerLocation(1.0d);

В зависимости от того, хотите ли вы сначала скрыть левый или правый компонент.

1 голос
/ 29 июня 2016

@ 0 __'s answer - это подсказка, что вы должны использовать AncestorListener для установки расположения делителя, и учесть это (ComponentListener недостаточно, Я не уверен почему).

Однако этого недостаточно : если плоскость разделения каким-либо образом изменяется (например, потому что ее менеджер по расположению решил, что это должно быть, когда размер кадра был изменен), крошечная доля компонента, который вы хотели скрыть все равно покажу. Это связано с тем, что минимальный размер компонента не равен нулю. Чтобы решить проблему, нужно обнулить его с помощью setMinimumSize(new Dimension()) (как объяснено в , то есть в другом ответе ), но если это не вариант, вы можете взломать интерфейс разделенной панели:

Если вы используете стандарт BasicSplitPaneUI, вы можете взломать его keepHidden логическое поле и принудительно установить его на true, чтобы разделитель прилип к любой стороне:

sp.addAncestorListener(new AncestorListener() {
    @Override
    public void ancestorAdded(AncestorEvent event) {
        sp.setDividerLocation(1.0); // Divider is positioned
        Field m = BasicSplitPaneUI.class.getDeclaredField("keepHidden");
        m.setAccessible(true);
        m.set(sp.getUI(), true); // Divider position will stick
        //sp.removeAncestorListener(this); // Uncomment for a one-shot event
    }

    @Override public void ancestorRemoved(AncestorEvent event) { }
    @Override public void ancestorMoved(AncestorEvent event) { }
});
1 голос
/ 06 мая 2016

Чтобы обойти проблему, заключающуюся в том, что setDividerLocation(1.0) не работает, пока кадр не станет отображаемым, можно использовать AncestorListener:

sp.addAncestorListener(new AncestorListener {
  def ancestorAdded  (event: AncestorEvent): Unit = sp.setDividerLocation(1.0)

  def ancestorRemoved(event: AncestorEvent): Unit = ()
  def ancestorMoved  (event: AncestorEvent): Unit = ()
})
...