2

右側のコンポーネントの幅が一定である JSplitPane (水平分割) を実装したい。つまり、仕切りをドラッグすると正しいサイズに戻ります。ゼロ幅。

右側のコンポーネントを再表示するには、ユーザーは分割線を十分に左にドラッグできます。

私はこれをほとんど機能させていますが、ウィンドウサイズを変更する量と速度に応じてウィンドウのサイズを変更すると、ディバイダージャンプが適切なコンポーネントを表示または非表示にします。私が望むのは、「状態」を変更しないことですつまり、右のコンポーネントが表示されていない場合は非表示のままにする必要があり、その逆も同様です。

私はたくさんのことを試しましたが、主な障害は、ユーザーがマウスを介して仕切りをドラッグしたか、コード (私の仕切りロジックおよび/または JSplitPane 内部ロジック) が仕切りの位置を変更したかを知る方法がないことです。 .

これは自己完結型のテスト ケースです。これを実行し、水平の仕切りをドラッグして右側のパネルを非表示または表示し、非表示/表示されているウィンドウのサイズを変更してみてください。

Mac OS X Java 1.6 (Apple) または Java 7 (Oracle) では意図したとおりに動作しません。Oracle のものを使用すると、レンダリングが大幅に遅くなり、問題がより深刻になります。ウィンドウのサイズ変更はゆっくりと機能しますが、ウィンドウ サイズをすばやく変更すると問題が発生します。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;

import net.miginfocom.swing.MigLayout;

public class SplitTest {
    public static class MySplitPane extends JSplitPane {
        boolean m_RightCollapsed;

        public MySplitPane(int orientation, JComponent left, JComponent right) {
            super(orientation, left, right);

            addPropertyChangeListener(new PropertyChangeListener() {

                @Override
                public void propertyChange(PropertyChangeEvent evt) {

                }
            });
            addComponentListener(new ComponentListener() {

                @Override
                public void componentShown(ComponentEvent e) {
                    reposDivider();
                }

                @Override
                public void componentResized(ComponentEvent e) {
                    reposDivider();
                }

                @Override
                public void componentMoved(ComponentEvent e) {
                    reposDivider();
                }

                @Override
                public void componentHidden(ComponentEvent e) {
                }
            });

        }

        public void reposDivider() {
            setDividerLocation(getDividerLocation());
        }

        public void setDividerLocation(int location) {
            int newLocation;
            m_RightCollapsed = location > getSize().width - getRightComponent().getPreferredSize().width / 2;
            if (m_RightCollapsed)
                newLocation = getSize().width;
            else
                newLocation = getSize().width - getInsets().right - getDividerSize() - getRightComponent().getPreferredSize().width;
            super.setDividerLocation(newLocation);
        }
    }
    static class MyScrollable extends JPanel implements Scrollable {
        int m_Height;

        public MyScrollable(int height) {
            m_Height = height;
        }

        @Override
        public void paint(java.awt.Graphics g) {
            super.paint(g);
            g.setColor(Color.CYAN);
            g.fillOval(0, 0, getWidth(), 500);
        }

        @Override
        public Dimension getPreferredScrollableViewportSize() {
            //return super.getPreferredSize();
            return new Dimension(100, m_Height);
        }

        @Override
        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
            // TODO Auto-generated method stub
            return 10;
        }

        @Override
        public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 20;
        }

        @Override
        public boolean getScrollableTracksViewportWidth() {
            return true;
        }

        @Override
        public boolean getScrollableTracksViewportHeight() {
            return false;
        }

    }

    public static class ShrinkGrow extends JPanel {
        public ShrinkGrow(final JComponent component, final JSplitPane split) {
            JButton grow = new JButton("+++");
            JButton shrink = new JButton("---");
            add(grow);
            add(shrink);

            grow.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Dimension oldSize = component.getPreferredSize();
                    Dimension newSize = new Dimension(oldSize.width, oldSize.height + 10);
                    component.setPreferredSize(newSize);
                    component.setSize(newSize);
                }
            });
            shrink.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Dimension oldSize = component.getPreferredSize();
                    Dimension newSize = new Dimension(oldSize.width, oldSize.height - 10);
                    component.setPreferredSize(newSize);
                    component.setSize(newSize);
                }
            });
        }
    }

    public static void main(String[] args) {
        JFrame window = new JFrame();

        JPanel mainView = new JPanel();
        JPanel top = new JPanel();
        top.setLayout(new BoxLayout(top, BoxLayout.Y_AXIS));
        JPanel bottom = new JPanel();
        bottom.setLayout(new BoxLayout(bottom, BoxLayout.Y_AXIS));

        final JSplitPane rightSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT);

        JPanel topContent = new MyScrollable(200);
        JPanel topFixed = new ShrinkGrow(topContent, rightSplit);
        topFixed.setLayout(new BoxLayout(topFixed, BoxLayout.X_AXIS));

        JScrollPane topFlexible = new JScrollPane(topContent);
        topFlexible.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        topFlexible.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        JPanel bottomContent = new MyScrollable(300);
        JPanel bottomFixed = new ShrinkGrow(bottomContent, rightSplit);
        bottomFixed.setLayout(new BoxLayout(bottomFixed, BoxLayout.X_AXIS));

        JScrollPane bottomFlexible = new JScrollPane(bottomContent);
        bottomFlexible.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        bottomFlexible.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        mainView.setBackground(Color.red);
        topFixed.setBackground(Color.green);
        topContent.setBackground(Color.green.darker());
        bottomFixed.setBackground(Color.blue);
        bottomContent.setBackground(Color.blue.darker());

        mainView.setMinimumSize(new Dimension(100, 100));
        mainView.setPreferredSize(new Dimension(400, 300));
        mainView.setMaximumSize(new Dimension(10000, 10000));

        topFixed.setMinimumSize(new Dimension(topFixed.getMinimumSize().width, 30));
        topFixed.setPreferredSize(new Dimension(topFixed.getPreferredSize().width, 30));
        topFixed.setMaximumSize(new Dimension(topFixed.getMaximumSize().width, 30));

        bottomFixed.setMinimumSize(new Dimension(bottomFixed.getMinimumSize().width, 40));
        bottomFixed.setPreferredSize(new Dimension(bottomFixed.getPreferredSize().width, 40));
        bottomFixed.setMaximumSize(new Dimension(bottomFixed.getMaximumSize().width, 40));

        topContent.setPreferredSize(new Dimension(100, 500));
        bottomContent.setPreferredSize(new Dimension(100, 400));

        top.add(topFixed);
        top.add(topFlexible);
        bottom.add(bottomFixed);
        bottom.add(bottomFlexible);
        rightSplit.setLeftComponent(top);
        rightSplit.setRightComponent(bottom);

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

        final JSplitPane mainSplit = new MySplitPane(JSplitPane.HORIZONTAL_SPLIT, mainView, rightSplit);

        window.add(mainSplit);
        window.pack();
        window.setVisible(true);
    }
}
4

3 に答える 3

5

イベントをキャッチできるかどうかはわかりませんdraggingが、確実にイベントをキャッチできますpropertyChange。の仕切りを移動した後のイベントのキャッチは、 JSplitPaneクラスJSplitPaneを介して可能になります。このリスナーが変更されたディバイダーロケーションイベントをリッスンするように、パラメーターとしてを指定してくださいPropertyChangeListenerDIVIDER_LOCATION_PROPERTYこれをメソッドの最初のパラメーターとして指定しない場合、 'sメソッドが値として返されるaddPropertyChangeListener()場合は、いつでも条件ステートメントを配置できます。PropertyChangeEventgetPropertyName()dividerLocation

jSplitPane1.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent pce) {
    // do here
}
});
于 2013-01-20T16:28:59.197 に答える
2

JSplitPane Divider に MouseListener を追加して、ディバイダーがドラッグされていることを検出します。ドラッグすると、プロパティ変更イベントに応答します。サンプル:

https://community.oracle.com/thread/1352161?start=0&tstart=0

SplitPaneUI spui = splitPane.getUI();
    if (spui instanceof BasicSplitPaneUI) {
      // Setting a mouse listener directly on split pane does not work, because no events are being received.
      ((BasicSplitPaneUI) spui).getDivider().addMouseListener(new MouseAdapter() {
        public void mouseClicked(MouseEvent e) {
于 2014-12-11T21:13:19.093 に答える
1

...ディバイダが十分に右にドラッグされない限り、右端のコンポーネントの幅はゼロになります。

右側のコンポーネントを再表示するには、ユーザーは分割線を十分に左にドラッグできます。

splitPane を無効にしてドラッグを無効にするだけのように思えますが、

次に、OneTouchExpandable() を true に設定します。「拡張可能」のいずれかを削除する必要がある場合があります

間違った方向への展開を無効にするボタン

于 2013-01-20T18:50:30.063 に答える