pivot-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Oliver Oyston" <Oliver.Oys...@actian.com>
Subject RE: Does Pivot support dockable windows?
Date Wed, 06 Feb 2013 00:09:37 GMT
So, you can implement a "mock" docking window interface that
approximates the docking functionality of Visual Studio fairly easily.
However, there are limitations: you can't reposition / drag / drop or
float the "windows" and you don't get dock guides or to use advanced
layout options. For many purposes this could be sufficient. 

 

When I implemented docking / MDI interface for a product we are
developing, I used a combination of TabPanes / SpliPanes for the tool
windows and logic for hiding/showing/closing as appropriate. 

 

We have an "Object Explorer" tool window that is permanently docked to
the left and an "Output" tool window that is permanently docked to the
bottom. The tool windows have a pin and a close button. 

 

Here is some sample code - I'd suggest creating a sample application,
replace the images with your own and have a "play" and see how it all
hangs together. Once you understand how it hangs together you should be
fairly easily able to customize it for your own needs.

 

Imports:

 

import org.apache.pivot.beans.BXML;

import org.apache.pivot.serialization.SerializationException;

import org.apache.pivot.wtk.Button;

import org.apache.pivot.wtk.ButtonPressListener;

import org.apache.pivot.wtk.Component;

import org.apache.pivot.wtk.ComponentMouseButtonListener;

import org.apache.pivot.wtk.Mouse;

import org.apache.pivot.wtk.PushButton;

import org.apache.pivot.wtk.SplitPane;

import org.apache.pivot.wtk.TabPane;

 

Code Behind:

 

    /**

     * The main split bar of the application.

     */

    @BXML

    private SplitPane mainSplitter;

 

    /**

     * The output tool window tab pane.

     */

    @BXML private TabPane outputToolWindowTabPane;

 

    /**

     * The output tool window split pane.

     */

    @BXML private SplitPane outputToolWindowSplitPane;

 

    /**

     * The output tool window pin button.

     */

    @BXML private PushButton outputToolWindowPinPushButton;

 

    /**

     * The output tool window close button.

     */

    @BXML private PushButton outputToolWindowClosePushButton;

 

    /**

     * The object explorer tool window tab pane.

     */

    @BXML private TabPane objectExplorerToolWindowTabPane;

 

    /**

     * The object explorer tool window pin button.

     */

    @BXML private PushButton objectExplorerToolWindowPinPushButton;

 

    /**

     * The object explorer tool window close button.

     */

    @BXML private PushButton objectExplorerToolWindowClosePushButton;

 

    /**

     * The state that the object explorer tool window is currently in.

     */

    private ToolWindowState objectExplorerToolWindowState =
ToolWindowState.OPEN;

 

    /**

     * The state that the output tool window is currently in.

     */

    private ToolWindowState outputToolWindowState =
ToolWindowState.COLLAPSED;

 

    /**

     * An enumeration of the possible tool window states.

     */

    public enum ToolWindowState

    {

        /**

         * The tool window is open.

         */

        OPEN,

 

        /**

         * The tool window is collapsed.

         */

        COLLAPSED,

 

        /**

         * The tool window is closed.

         */

        CLOSED

    }

 

    private float objectExplorerSplitRatio = 0;

    private float outputToolWindowSplitRatio = 0;

 

    /**

     * An enumeration of the available tool windows.

     */

    public enum ToolWindow

    {

        /**

         * The object explorer tool window.

         */

        OBJECT_EXPLORER,

 

        /**

         * The output tool window.

         */

        OUTPUT,

    }

 

    private class ToolWindowButtonListener implements
ButtonPressListener

    {

        private ToolWindow window;

        private ToolWindowState state;

 

        public ToolWindowButtonListener(ToolWindow window,
ToolWindowState state) {

            this.window = window;

            this.state = state;

        }

        @Override

        public void buttonPressed(Button button) {

            setToolWindowToState(window, state);

        }

    }

 

    /**

     * Instantiate a window button listener.

     */

    private void addWindowButtonListener(Button button, ToolWindow
window, ToolWindowState state) {

        button.getButtonPressListeners().add(new
ToolWindowButtonListener(window, state));

    }

 

    /**

     * Sets the state of a tool window.

     *

     * @param toolWindow The tool window.

     * @param state The state that we wish to set the tool window to.

     */

    public void setToolWindowToState(ToolWindow toolWindow,
ToolWindowState state){

 

        // If we are dealing with the output window and it is already in
the required state then do nothing

        if ((toolWindow == ToolWindow.OUTPUT) && (state ==
outputToolWindowState)){

            return;

        }

 

        // If we are dealing with the object explorer window and it is
already in the required state then do nothing

        if ((toolWindow == ToolWindow.OBJECT_EXPLORER) && (state ==
objectExplorerToolWindowState)){

            return;

        }

 

        // Initialize variables as appropriate

        SplitPane splitPane = null;

        TabPane tabPane = null;

        int closedSplitRatio = 0;

        float openSplitRatio = 0;

 

        // Amend variables as appropriate for the tool window

        switch (toolWindow) {

            case OBJECT_EXPLORER:

                objectExplorerToolWindowState = state;

                splitPane = mainSplitter;

                tabPane = objectExplorerToolWindowTabPane;

                closedSplitRatio = 0;

                openSplitRatio = objectExplorerSplitRatio;

                break;

            case OUTPUT:

                outputToolWindowState = state;

                splitPane = outputToolWindowSplitPane;

                tabPane = outputToolWindowTabPane;

                closedSplitRatio = 1;

                openSplitRatio = outputToolWindowSplitRatio;

                break;

        }

 

        // Perform the required action

        switch (state) {

            case OPEN:

                hideToolWindowTabPane(tabPane);

                showToolPane(splitPane, openSplitRatio);

                break;

            case COLLAPSED:

                outputToolWindowSplitRatio =
outputToolWindowSplitPane.getSplitRatio();

                objectExplorerSplitRatio = mainSplitter.getSplitRatio();

                hideToolPane(splitPane, closedSplitRatio);

                showToolWindowTabPane(tabPane);

                break;

            case CLOSED:

                outputToolWindowSplitRatio =
outputToolWindowSplitPane.getSplitRatio();

                objectExplorerSplitRatio = mainSplitter.getSplitRatio();

                hideToolPane(splitPane, closedSplitRatio);

                hideToolWindowTabPane(tabPane);

                break;

        }

    }

 

    /**

     * Shows a tab pane.

     *

     * @param tabPane The tab pane to show.

     */

    private void showToolWindowTabPane(TabPane tabPane) {

        tabPane.setVisible(true);

    }

 

    /**

     * Hides a tool pane.

     *

     * @param splitPane The split pane that houses the tool pane.

     * @param splitRatio The split ratio that corresponds to hidden.

     */

    private void hideToolPane(SplitPane splitPane, int splitRatio) {

 

        // Set the split pane to the specified ratio

        splitPane.setSplitRatio(splitRatio);

 

        // Set the styles on the split pane.

        try {

 
splitPane.setStyles("{splitterHandlePrimaryColor:'#0000F0',splitterThick
ness:0}");

        } catch (SerializationException e) {

            e.printStackTrace();

        }

 

        // Lock the split pane.

        splitPane.setLocked(true);

    }

 

    /**

     * Hides a tool window tab pane.

     *

     * @param tabPane The tab pane to hide.

     */

    private void hideToolWindowTabPane(TabPane tabPane) {

        tabPane.setVisible(false);

    }

 

    /**

     * Shows a tool pane.

     *

     * @param splitPane The split pane that houses the tool window.

     * @param splitRatio The split ratio that corresponds to the tool
pane been shown.

     */

    private void showToolPane(SplitPane splitPane, float splitRatio) {

 

        // Set the split ration.

        splitPane.setSplitRatio(splitRatio);

 

        // Set the style for the split pane.

        try {

 
splitPane.setStyles("{splitterHandlePrimaryColor:'#0000F0',splitterThick
ness:6}");

        } catch (SerializationException e) {

            e.printStackTrace();

        }

 

        // Unlock the split pane.

        splitPane.setLocked(false);

    }

    

    /**

     * Mouse button listener for a tool window.

     */

    private class ToolWindowComponentMouseButtonListener implements
ComponentMouseButtonListener {

 

        // The tool window that the listener is for.

        private ToolWindow toolWindow;

 

        /**

         * Initializes a new instance of the class.

         *

         * @param toolWindow The tool window that the listener
corresponds to.

         */

        public ToolWindowComponentMouseButtonListener(ToolWindow
toolWindow){

            super();

            this.toolWindow = toolWindow;

        }

 

        /**

         * Mouse down event for the tool window tab pane.

         *

         * @param component The component.

         * @param button The mouse button that has gone down.

         * @param x The 'x' coordinate of the mouse down.

         * @param y The 'y' coordinate of the mouse down.

         * @return Whether the event has been handled.

         */

        @Override

        public boolean mouseDown(Component component, Mouse.Button
button, int x, int y) {

 

            // Get the tab pane.

            TabPane tabPane = (TabPane)component;

 

            // Get the component at the location of the mouse down.

            Component comp = tabPane.getComponentAt(x, y);

 

            /**

             * If we don't have a component then return.

             */

            if(comp == null){

                return true;

            }

 

            // We have a component so this must be the 'button' so set
the tool window to open.

            setToolWindowToState(toolWindow, ToolWindowState.OPEN);

 

            // return handled

            return true;

        }

 

        @Override

        public boolean mouseUp(Component component, Mouse.Button button,
int x, int y) {

            // No specific implementation required.

            return false;

        }

 

        @Override

        public boolean mouseClick(Component component, Mouse.Button
button, int x, int y, int count) {

            // No specific implementation required.

            return false;

        }

    }

 

And hooking everything up in  the constructor:

 

         // Hook up the window buttons

         addWindowButtonListener(outputToolWindowPinPushButton,
ToolWindow.OUTPUT, ToolWindowState.COLLAPSED);

         addWindowButtonListener(objectExplorerToolWindowPinPushButton,
ToolWindow.OBJECT_EXPLORER, ToolWindowState.COLLAPSED);

         addWindowButtonListener(outputToolWindowClosePushButton,
ToolWindow.OUTPUT, ToolWindowState.CLOSED);

 
addWindowButtonListener(objectExplorerToolWindowClosePushButton,
ToolWindow.OBJECT_EXPLORER, ToolWindowState.CLOSED);

 

         objectExplorerSplitRatio = 0.25f;

         outputToolWindowSplitRatio = 0.7f;

 

         mainSplitter.setPrimaryRegion(SplitPane.Region.TOP_LEFT);

 

         setToolWindowToState(ToolWindow.OBJECT_EXPLORER,
ToolWindowState.OPEN);

 

 

         // Add listener to the output tool window tab pane

 
outputToolWindowTabPane.getComponentMouseButtonListeners().add(new
ToolWindowComponentMouseButtonListener(ToolWindow.OUTPUT));

 

         // Add listener to the object explorer tool window tab pane

 
objectExplorerToolWindowTabPane.getComponentMouseButtonListeners().add(n
ew ToolWindowComponentMouseButtonListener(ToolWindow.OBJECT_EXPLORER));

 

The bxml is as follows:

 

<?xml version="1.0" encoding="utf-8"?>

<Window title="%mainAppTitle" 

    maximized="true" 

     bxml:id="mainWindow" 

     xmlns:bxml="http://pivot.apache.org/bxml" 

     xmlns:content="org.apache.pivot.wtk.content" 

     xmlns="org.apache.pivot.wtk">

  <!-- Main window content -->

  <content>

    <TablePane>

      <columns>

        <TablePane.Column width="1*" />

      </columns>

      <rows>

      <!-- Main Row -->

        <TablePane.Row height="1*">

          <SplitPane bxml:id="outputToolWindowSplitPane"
orientation="vertical" splitRatio="1" locked="true"
styles="{splitterHandlePrimaryColor:'#0000F0',splitterThickness:0}">

            <left>

              <TablePane>

                <columns>

                  <TablePane.Column width="-1" />

                  <TablePane.Column width="1*" />

                </columns>

                <rows>

                  <TablePane.Row height="1*">

                    <BoxPane styles="{backgroundColor:'#E8E8E8'}">

                      <TabPane bxml:id="objectExplorerToolWindowTabPane"
collapsible="true" selectedIndex="-1" visible="false"
styles="{backgroundColor:'#FFFFFF',tabOrientation:'vertical',
activeTabColor:'#F7F5EE', inactiveTabColor:'#F7F5EE'}">

                        <BoxPane>

                          <TabPane.tabData>

                            <content:ButtonData
text="%titleInstanceExplorer" icon="@/images/obj-expl-16.png" />

                          </TabPane.tabData>

                        </BoxPane>

                      </TabPane>

                    </BoxPane>

                    <SplitPane bxml:id="mainSplitter" splitRatio="0.30"
styles="{splitterHandlePrimaryColor:'#0000F0'}">

                      <left>

                        <Border styles="{color:10}">

                          <content>

                            <TablePane>

                              <columns>

                                <TablePane.Column width="1*" />

                              </columns>

                              <TablePane.Row height="1*">

                                <TablePane>

                                  <columns>

                                    <TablePane.Column width="1*" />

                                  </columns>

                                  <rows>

                                    <TablePane.Row height="-1">

                                      <TablePane>

                                        <columns>

                                          <TablePane.Column width="-1"
/>

                                          <TablePane.Column width="1*"
/>

                                        </columns>

                                        <rows>

                                          <TablePane.Row>

                                            <BoxPane
orientation="horizontal" styles="{padding:2, fill:true}">

                                              <Label
text="%titleObjectExplorer" styles="{color:'#ffffff',font:{bold:true}}"
/>

                                            </BoxPane>

                                            <BoxPane
orientation="horizontal" styles="{padding:0, fill:true,
horizontalAlignment:'right'}">

                                              <PushButton
bxml:id="objectExplorerToolWindowPinPushButton" styles="{toolbar:true}"
tooltipText="%tipAutoHide">

                                                <buttonData>

                                                  <content:ButtonData
icon="@/images/winpin-14.png" />

                                                </buttonData>

                                              </PushButton>

                                              <PushButton
bxml:id="objectExplorerToolWindowClosePushButton"
styles="{toolbar:true}" tooltipText="%tipClose">

                                                <buttonData>

                                                  <content:ButtonData
icon="@/images/winclose-14.png" />

                                                </buttonData>

                                              </PushButton>

                                            </BoxPane>

                                          </TablePane.Row>

                                        </rows>

                                      </TablePane>

                                    </TablePane.Row>

                                    <TablePane.Row height="1*">

                                        <!-- Left docked tool window
content -->

                                    </TablePane.Row>

                                  </rows>

                                </TablePane>

                              </TablePane.Row>

                            </TablePane>

                          </content>

                        </Border>

                      </left>

                      <right>

                          <!-- Main content here -->


                      </right>

                    </SplitPane>

                  </TablePane.Row>

                </rows>

              </TablePane>

            </left>

            <right>

              <Border styles="{color:10}">

                <content>

                  <TablePane>

                    <columns>

                      <TablePane.Column width="1*" />

                    </columns>

                    <rows>

                      <TablePane.Row height="-1">

                        <TablePane>

                          <columns>

                            <TablePane.Column width="1*" />

                            <TablePane.Column width="-1" />

                          </columns>

                          <rows>

                            <TablePane.Row>

                              <BoxPane orientation="horizontal"
styles="{padding:2, fill:true}">

                                <Label text="%titleOutputWindow"
styles="{color:'#ffffff'}" />

                              </BoxPane>

                              <BoxPane orientation="horizontal"
styles="{padding:0, fill:true}">

                                <PushButton
bxml:id="outputToolWindowPinPushButton" styles="{toolbar:true}"
tooltipText="%tipAutoHide">

                                  <buttonData>

                                    <content:ButtonData
icon="@/images/winpin-14.png" />

                                  </buttonData>

                                </PushButton>

                                <PushButton
bxml:id="outputToolWindowClosePushButton" styles="{toolbar:true}"
tooltipText="%tipClose">

                                  <buttonData>

                                    <content:ButtonData
icon="@/images/winclose-14.png" />

                                  </buttonData>

                                </PushButton>

                              </BoxPane>

                            </TablePane.Row>

                          </rows>

                        </TablePane>

                      </TablePane.Row>

                      <TablePane.Row height="1*">

                          <!-Bottom docked tool window content -->

                      </TablePane.Row>

                    </rows>

                  </TablePane>

                </content>

              </Border>

            </right>

          </SplitPane>

        </TablePane.Row>

        <!-- Output Tool Pane -->

        <TablePane.Row height="-1">

          <TabPane bxml:id="outputToolWindowTabPane" collapsible="true"
selectedIndex="-1" styles="{backgroundColor:'#E8E8E8'}">

            <BoxPane>

              <TabPane.tabData>

                <content:ButtonData text="%titleOutputWindow"
icon="@/images/output-16.png" />

              </TabPane.tabData>

            </BoxPane>

          </TabPane>

        </TablePane.Row>

      </rows>

    </TablePane>

  </content>

</Window>

 

You could implement floating windows (we have not) but it certainly not
trivial to do...

 

Hope this helps.

 

Oliver

 

From: Roger L. Whitcomb [mailto:Roger.Whitcomb@actian.com] 
Sent: Tuesday, February 05, 2013 9:38 AM
To: user@pivot.apache.org
Subject: RE: Does Pivot support dockable windows?

 

It is not the same as in Swing - I'll have to check with the developer
who did that work on our product.

 

~Roger

 

From: Schwartz, Cynthia L [mailto:cynthia.l.schwartz@intel.com] 
Sent: Monday, February 04, 2013 4:18 PM
To: user@pivot.apache.org
Subject: RE: Does Pivot support dockable windows?

 

Roger,

 

Yes eventually I would need floating windows.  How do you accomplish
dockable windows, is it similar to getting docking windows in Swing?

 

Thanks,

Cynthia

 

From: Schwartz, Cynthia L 
Sent: Monday, February 04, 2013 10:09 AM
To: user@pivot.apache.org
Subject: Does Pivot support dockable windows?

 

And if so, is there an example?  

 

Thanks,

Cynthia


Mime
View raw message