SWT 应用程序:可拖动选项卡是否可行?

SWT Application: Are Draggable Tabs Possible?

我正在使用 SWT 构建一个 Java 应用程序。该应用程序的要求之一是它有多个windows。与其拥有 "forever independent" windows,我认为实现一个功能会很酷,就像在大多数浏览器中那样,您有一个单一的表格 window,其中每个选项卡都可以被拖出以创建一个单独的window。在使用 Google 进行一些研究后,似乎可以实现此 using JavaFX,但是是否有可能(并且相对容易)在 SWT 中实现相同的功能?提前致谢。

虽然我的看法可能有点晚了,但还是在这里。下面的代码片段是一个粗略的 POC,它允许从 CTabFolder 中拖动项目,当项目被放到文件夹边界之外时,会打开一个 shell 以显示项目的内容。

public static void main( String[] args ) {
  Display display = new Display();
  final Shell shell = new Shell( display );
  shell.setLayout( new FillLayout() );
  final CTabFolder folder = new CTabFolder( shell, SWT.BORDER );
  for( int i = 0; i < 4; i++ ) {
    CTabItem item = new CTabItem( folder, SWT.CLOSE );
    item.setText( "Item " + i );
    Text text = new Text( folder, SWT.MULTI );
    text.setText( "Content for Item " + i );
    item.setControl( text );
  }
  Listener dragListener = new Listener() {
    private CTabItem dragItem;

    public void handleEvent( Event event ) {
      Point mouseLocation = new Point( event.x, event.y );
      switch( event.type ) {
        case SWT.DragDetect: {
          CTabItem item = folder.getItem( mouseLocation );
          if( dragItem == null && item != null ) {
            dragItem = item;
            folder.setCapture( true );
          }
          break;
        }
        case SWT.MouseUp: {
          if( dragItem != null && !folder.getBounds().contains( mouseLocation ) ) {
            popOut( dragItem, folder.toDisplay( mouseLocation ) );
            dragItem.dispose();
            dragItem = null;
          }
          break;
        }
      }
    }
  };
  folder.addListener( SWT.DragDetect, dragListener );
  folder.addListener( SWT.MouseUp, dragListener );
  shell.pack();
  shell.open();
  while( !shell.isDisposed() ) {
    if( !display.readAndDispatch() )
      display.sleep();
  }
  display.dispose();
}

private static void popOut( CTabItem tabItem, Point location ) {
  Control control = tabItem.getControl();
  tabItem.setControl( null );
  Shell itemShell = new Shell( tabItem.getParent().getShell(), SWT.DIALOG_TRIM | SWT.RESIZE );
  itemShell.setLayout( new FillLayout() );
  control.setParent( itemShell );
  control.setVisible( true ); // control is hidden by tabItem.setControl( null ), make visible again
  itemShell.pack();
  itemShell.setLocation( location );
  itemShell.open();
}

虽然此示例使用 CTabFolder,但也应该可以使用(本地)TabFolder

当然缺少的是拖动项目时的视觉反馈和中止拖动操作的方法(例如 Esc 键),可能还有更多东西...