Javafx 2 如何在选项卡窗格之间拖放选项卡节点

Javafx 2 如何在选项卡窗格之间拖放选项卡节点,javafx-2,javafx,javafx-8,Javafx 2,Javafx,Javafx 8,我正在研究这个例子。根据教程,我想在两个选项卡之间拖动选项卡。到目前为止,我成功地创建了这段代码,但我需要一些帮助才能完成这段代码 来源 我想这个转移可以完成吗 工作解决方案: import java.util.Random; 导入javafx.application.application; 导入javafx.beans.property.ObjectProperty; 导入javafx.beans.property.SimpleObject属性; 导入javafx.event.EventHa

我正在研究这个例子。根据教程,我想在两个选项卡之间拖动选项卡。到目前为止,我成功地创建了这段代码,但我需要一些帮助才能完成这段代码

来源

我想这个转移可以完成吗

工作解决方案:

import java.util.Random;
导入javafx.application.application;
导入javafx.beans.property.ObjectProperty;
导入javafx.beans.property.SimpleObject属性;
导入javafx.event.EventHandler;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.control.Tab;
导入javafx.scene.control.TabPane;
导入javafx.scene.input.ClipboardContent;
导入javafx.scene.input.DragEvent;
导入javafx.scene.input.Dragboard;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.input.TransferMode;
导入javafx.scene.layout.StackPane;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
公共类客户端扩展应用程序
{
私有静态最终字符串选项卡\u拖动\u KEY=“TAB”;
私有对象属性draggingTab;
@凌驾
公共无效开始(阶段primaryStage)
{
DragginTab=新的SimpleObject属性();
TabPane tabPane1=createTabPane();
TabPane tabPane2=createTabPane();
VBox根=新的VBox(10);
root.getChildren().addAll(tabPane1、tabPane2);
最终随机rng=新随机();

对于(int i=1;i非常感谢,它基本上工作正常。但是,当从第二个选项卡拖动到第一个/上部选项卡窗格时,选项卡的内容不会刷新,您需要更改选项卡或移动拆分分隔符。第二个/下部选项卡窗格始终正确刷新。目前为止,我还没有找到解决方法king the tabpane进行刷新不起作用。如果我能找到解决方案,我将不胜感激

编辑:找到了有效的解决方案

在setOnDragDropped事件处理程序中,我对选择添加选项卡的行进行了注释,然后添加了以下代码:

Platform.runLater(new Runnable() {
   @Override
   public void run() {
       tabPane.getSelectionModel().select(tab) ;
   }
});
现在成功了,再次感谢

编辑2:很抱歉,我不得不报告,它有时/大部分时间都能工作,但并不总是……仍在研究如何真正修复它


编辑3:至少现在我知道了问题的原因:当一个选项卡被删除并添加到另一个窗格时,从旧选项卡窗格中删除并不是即时的,然后旧窗格会禁用该选项卡上下文的更新,而该选项卡现在已经在另一个选项卡窗格中。这就是为什么它根本不会被绘制。当我放置Thread.sl时eep(500)(更短的睡眠时间不起作用)在删除和添加调用之间,一切正常。如果我设法找到解决方案,将在以后更新。

以下是我为此编写的代码。包括实现拖动移动机制的驱动程序和侦听器

  import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTree;

public class MovableTabbedPane extends JTabbedPane {

    private MovableTabbedPane  movableTabbedPane;
    public MovableTabbedPane() {
        super();
        movableTabbedPane = this;
        TabDragListener tabDragger = new TabDragListener();
        this.addMouseListener(tabDragger);
        this.addMouseMotionListener(tabDragger);        
    }

    private class TabDragListener implements MouseListener, MouseMotionListener {

        Point p0;
        double y0, y;
        Component current;
        String title;

        public void mousePressed(MouseEvent e) {
            p0 = e.getPoint();
            y0=p0.getY();

            for (int i = 0; i < getTabCount(); i++) {
                Rectangle bounds = getBoundsAt(i);
                if (bounds.contains(p0)) {
                    current = MovableTabbedPane.this.getComponentAt(i);   
                    title =MovableTabbedPane.this.getTitleAt(i);
                }
            }
        };

        public void mouseDragged(MouseEvent e) {
            Point p = e.getPoint();
            y=p.getY();

            if (current != null) {
                // check for a significant horizontal drag
                if(Math.abs(y-y0)< 40 && p.distance(p0)>5){
                    int targetIndex = MovableTabbedPane.this.getUI().tabForCoordinate(MovableTabbedPane.this,
                            e.getX(), e.getY());
                    // target index should be valid and also not be same as original tab's index
                    if(targetIndex!=-1 && targetIndex!=getSelectedIndex()){         
                        movableTabbedPane.remove(current);
                        movableTabbedPane.insertTab(title, null, current, null, targetIndex);
                        setSelectedIndex(targetIndex);
                    }
                }
            } 
        }

        public void mouseMoved(MouseEvent arg0) {}

        public void mouseClicked(MouseEvent arg0) {}

        public void mouseEntered(MouseEvent arg0) {}

        public void mouseExited(MouseEvent arg0) {}

        public void mouseReleased(MouseEvent arg0) {
            current=null;
            title =null;
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        MovableTabbedPane pane = new MovableTabbedPane();
        pane.add(new JTree(), "Tree 0");
        pane.add(new JTextArea(" Hello"), "Tree 1");
        pane.add(new JFileChooser(), "Tree 2");
        pane.add(new JSpinner(), "Tree 3");
        pane.add(new JSlider(),"Tree 4");
        frame.getContentPane().add(pane);
        frame.setBounds(100, 100, 400, 400);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.setVisible(true);
    }
}
导入java.awt.Component;
导入java.awt.Point;
导入java.awt.Rectangle;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseListener;
导入java.awt.event.MouseMotionListener;
导入java.awt.event.WindowAdapter;
导入java.awt.event.WindowEvent;
导入javax.swing.JFileChooser;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JSlider;
导入javax.swing.JSpinner;
导入javax.swing.JTabbedPane;
导入javax.swing.JTextArea;
导入javax.swing.JTree;
公共类MovableTabbedPane扩展了JTabbedPane{
私有可移动选项卡窗格可移动选项卡窗格;
公共可移动选项卡窗格(){
超级();
movableTabedPane=此;
TabDragListener tabDragger=新的TabDragListener();
这是addMouseListener(tabDragger);
this.addMouseMotionListener(tabDragger);
}
私有类TabDragListener实现MouseListener、MouseMotionListener{
p0点;
双y0,y;
分量电流;
字符串标题;
公共无效鼠标按下(MouseEvent e){
p0=e.getPoint();
y0=p0.getY();
for(int i=0;i5){
int targetIndex=movableTabedPane.this.getUI().tabForCoordinate(movableTabedPane.this,
e、 getX(),e.getY());
//目标索引应该有效,并且与原始选项卡的索引不同
如果(targetIndex!=-1&&targetIndex!=getSelectedIndex()){
movableTabbedPane.remove(当前);
movableTabbedPane.insertTab(标题、null、当前、null、targetIndex);
设置选定的索引(targetIndex);
}
}
} 
}
public void mouseMoved(MouseEvent arg0){}
public void mouseClicked(MouseEvent arg0){}
public void mouseEntered(MouseEvent arg0){}
public void mouseExited(MouseEvent arg0){}
公共无效MouseEvent arg0{
电流=零;
title=null;
}
}
公共静态void main(字符串[]args){
JFrame=新JFrame();
MOVABLETABEDPANE pane=新的MOVABLETABEDPANE();
添加(新JTree(),“树0”);
添加(新JTextArea(“Hello”),“tree1”);
添加(新的JFileChooser(),“树2”);
添加(新的JSpinner(),“树3”);
添加(新的JSlider(),“树4”);
import java.util.Random;
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class client extends Application
{

    private static final String TAB_DRAG_KEY = "tab";
    private ObjectProperty<Tab> draggingTab;

    @Override
    public void start(Stage primaryStage)
    {
        draggingTab = new SimpleObjectProperty<>();
        TabPane tabPane1 = createTabPane();
        TabPane tabPane2 = createTabPane();
        VBox root = new VBox(10);
        root.getChildren().addAll(tabPane1, tabPane2);
        final Random rng = new Random();
        for (int i = 1; i <= 8; i++)
        {
            final Tab tab = createTab("Tab " + i);
            final StackPane pane = new StackPane();
            int red = rng.nextInt(256);
            int green = rng.nextInt(256);
            int blue = rng.nextInt(256);
            String style = String.format("-fx-background-color: rgb(%d, %d, %d);", red, green, blue);
            pane.setStyle(style);
            final Label label = new Label("This is tab " + i);
            label.setStyle(String.format("-fx-text-fill: rgb(%d, %d, %d);", 256 - red, 256 - green, 256 - blue));
            pane.getChildren().add(label);
            pane.setMinWidth(600);
            pane.setMinHeight(250);
            tab.setContent(pane);
            if (i <= 4)
            {
                tabPane1.getTabs().add(tab);
            }
            else
            {
                tabPane2.getTabs().add(tab);
            }
        }
        primaryStage.setScene(new Scene(root, 600, 600));
        primaryStage.show();
    }

    public static void main(String[] args)
    {
        launch(args);
    }

    private TabPane createTabPane()
    {
        final TabPane tabPane = new TabPane();
        tabPane.setOnDragOver(new EventHandler<DragEvent>()
        {
            @Override
            public void handle(DragEvent event)
            {
                final Dragboard dragboard = event.getDragboard();
                if (dragboard.hasString()
                        && TAB_DRAG_KEY.equals(dragboard.getString())
                        && draggingTab.get() != null
                        && draggingTab.get().getTabPane() != tabPane)
                {
                    event.acceptTransferModes(TransferMode.MOVE);
                    event.consume();
                }
            }
        });
        tabPane.setOnDragDropped(new EventHandler<DragEvent>()
        {
            @Override
            public void handle(DragEvent event)
            {
                final Dragboard dragboard = event.getDragboard();
                if (dragboard.hasString()
                        && TAB_DRAG_KEY.equals(dragboard.getString())
                        && draggingTab.get() != null
                        && draggingTab.get().getTabPane() != tabPane)
                {
                    final Tab tab = draggingTab.get();
                    tab.getTabPane().getTabs().remove(tab);
                    tabPane.getTabs().add(tab);
                    tabPane.getSelectionModel().select(tab);
                    event.setDropCompleted(true);
                    draggingTab.set(null);
                    event.consume();
                }
            }
        });
        return tabPane;
    }

    private Tab createTab(String text)
    {
        final Tab tab = new Tab();
        final Label label = new Label(text);
        tab.setGraphic(label);
        label.setOnDragDetected(new EventHandler<MouseEvent>()
        {
            @Override
            public void handle(MouseEvent event)
            {
                Dragboard dragboard = label.startDragAndDrop(TransferMode.MOVE);
                ClipboardContent clipboardContent = new ClipboardContent();
                clipboardContent.putString(TAB_DRAG_KEY);
                dragboard.setContent(clipboardContent);
                draggingTab.set(tab);
                event.consume();
            }
        });
        return tab;
    }
}
Platform.runLater(new Runnable() {
   @Override
   public void run() {
       tabPane.getSelectionModel().select(tab) ;
   }
});
  import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTree;

public class MovableTabbedPane extends JTabbedPane {

    private MovableTabbedPane  movableTabbedPane;
    public MovableTabbedPane() {
        super();
        movableTabbedPane = this;
        TabDragListener tabDragger = new TabDragListener();
        this.addMouseListener(tabDragger);
        this.addMouseMotionListener(tabDragger);        
    }

    private class TabDragListener implements MouseListener, MouseMotionListener {

        Point p0;
        double y0, y;
        Component current;
        String title;

        public void mousePressed(MouseEvent e) {
            p0 = e.getPoint();
            y0=p0.getY();

            for (int i = 0; i < getTabCount(); i++) {
                Rectangle bounds = getBoundsAt(i);
                if (bounds.contains(p0)) {
                    current = MovableTabbedPane.this.getComponentAt(i);   
                    title =MovableTabbedPane.this.getTitleAt(i);
                }
            }
        };

        public void mouseDragged(MouseEvent e) {
            Point p = e.getPoint();
            y=p.getY();

            if (current != null) {
                // check for a significant horizontal drag
                if(Math.abs(y-y0)< 40 && p.distance(p0)>5){
                    int targetIndex = MovableTabbedPane.this.getUI().tabForCoordinate(MovableTabbedPane.this,
                            e.getX(), e.getY());
                    // target index should be valid and also not be same as original tab's index
                    if(targetIndex!=-1 && targetIndex!=getSelectedIndex()){         
                        movableTabbedPane.remove(current);
                        movableTabbedPane.insertTab(title, null, current, null, targetIndex);
                        setSelectedIndex(targetIndex);
                    }
                }
            } 
        }

        public void mouseMoved(MouseEvent arg0) {}

        public void mouseClicked(MouseEvent arg0) {}

        public void mouseEntered(MouseEvent arg0) {}

        public void mouseExited(MouseEvent arg0) {}

        public void mouseReleased(MouseEvent arg0) {
            current=null;
            title =null;
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        MovableTabbedPane pane = new MovableTabbedPane();
        pane.add(new JTree(), "Tree 0");
        pane.add(new JTextArea(" Hello"), "Tree 1");
        pane.add(new JFileChooser(), "Tree 2");
        pane.add(new JSpinner(), "Tree 3");
        pane.add(new JSlider(),"Tree 4");
        frame.getContentPane().add(pane);
        frame.setBounds(100, 100, 400, 400);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.setVisible(true);
    }
}