I\'m working on example from this tutorial. Based on the tutorial I want to drag tabs between two tabs. So far I managed to create this code but I need some help in order to
Thank you very much for this, it works basically well. However, when dragging to the first / upper tabpane from the second one, the content of the tab does not get refreshed, you need to change the tab or move the split divider. The second / lower tabpane does always refresh correctly. I have not found a remedy for this so far, asking the tabpane to do a refresh does not work. I would really appreciated if I could find a solution for this.
Edit: found a working solution
In the setOnDragDropped event handler I commented the line that selects the added tab, then added the following code:
Platform.runLater(new Runnable() {
@Override
public void run() {
tabPane.getSelectionModel().select(tab) ;
}
});
now it works. Thanks again
Edit 2: I'm sorry that I have to report that it works sometimes / most of the time, but not always.. still investigating on how to fix it for real.
Edit 3: At least now i know what causes the problem: when one tab is removed and added to the other pane, the removal from the old tabpane is not instant, and then the old pane disable the update of the context of that tab which is now already in the other tabpane. that's why it does not get drawn at all. When I put a Thread.sleep(500) (shorter sleep time is not working) between the calls to remove and add, everything works fine. Will update later if I manage to find a solution.
Here is the code I wrote for this. Includes driver and listener that implements the dragging moving mechanism.
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);
}
}