7

にはJSplitPanesetOneTouchExpandableをすばやく完全に非表示または完全に表示するための2つのボタンを提供するメソッドがありますJSplitPane

私の質問は、プログラムでの非表示ボタンを「クリック」する方法です。JSplitPane

私は自分自身を間違って説明したかもしれません。分割ペインに最初に2つのコンポーネントのうちの1つだけを表示したい(これは私がクリックすることを意味します)。

これは機能します:

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.01.0も適切なコンポーネントは非表示になりません。これが私の問題です!

4

6 に答える 6

6
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);
            }
        });
    }
}
于 2012-02-07T13:54:32.187 に答える
4

これは別の解決策であり、おそらく少し汚いですが、それは機能します;)コードがそれ自体を物語っていることを願っています。

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();
    }
}
于 2018-05-31T21:03:37.023 に答える
3

あなたは単にこれを使うことができます:

public void setDividerLocation(double proportionalLocation)

splitPane.setDividerLocation(0.0d);

また。

splitPane.setDividerLocation(1.0d);

左側のコンポーネントを最初に非表示にするか、右側のコンポーネントを非表示にするかによって異なります。

于 2012-02-07T13:53:17.450 に答える
1

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 = ()
})
于 2016-05-06T00:38:03.713 に答える
1

@ 0__の答えAncestorListenerは、を使用して仕切りの位置を設定し、それを考慮に入れる必要があるというヒントです(ComponentListener十分ではありません。理由はわかりません)。

ただし、それだけでは不十分です。分割平面のサイズが変更された場合(たとえば、フレームのサイズが変更されたときにレイアウトマネージャーがサイズ変更する必要があると判断したため)、非表示にするコンポーネントのごく一部が表示されます。これは、コンポーネントの最小サイズがゼロではないためです。(他の回答setMinimumSize(new Dimension())で説明されているように)それをゼロにすることで対処できますが、それがオプションでない場合は、分割ペインUIにハックすることができます。

標準を使用している場合は、ブールフィールドをBasicSplitPaneUIハックして強制的にに設定できるため、仕切りはどちらかの側に固定されます。keepHiddentrue

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) { }
});
于 2016-06-29T13:07:59.577 に答える
0

他の答えを組み合わせるdoClickと、経由の遅延AncestorListenerは私のために働いた。説明を参照してください:

if (wantHiddenPane) {
  // The splitPane's "onload" event approximation =
  // the hierarchy ancestor changes when the pane gets packed/made visible on screen
  // Which is when the splitPane dimensions have been initialized based on available screen space
  // So that edits to the divider location can take effect after that.
   splitPane.addAncestorListener(new AncestorListener() {
       public void ancestorAdded(AncestorEvent ev) {
          // Pressing the oneTouch button shows/hides a pane while remembering the last custom dragged size
          BasicSplitPaneUI ui = (BasicSplitPaneUI) splitPane.getUI();
          JButton neededOneTouchBtn = (JButton) ui.getDivider().getComponent(isHiddenPaneLeftTop ? 0 : 1);
          neededOneTouchBtn.doClick();
        }
        // only run once
         splitPane.removeAncestorListener(this);
       }

       public void ancestorRemoved(AncestorEvent ev) {
       }

       public void ancestorMoved(AncestorEvent ev) {
       }
     });
 }
于 2021-09-13T20:39:40.223 に答える