When there is only a single Dockable in a StackDockStation (which is on a splitDockStation) the the StackDockStation.getDockParent() returns null, but as soon as more then one Dockable is added then StackDockStation.getDockParent() does not return null. Also the StackDockStation does not show any tabs if there is only one dockable. This behavior is understandable, but is it configurable ? Can you force the StackDockStation to always show tabs ? (Not sure if relevant but I am using the BubbleTheme)
Are you certain the StackDockStation is in the tree at all? Having no parent suggest otherwise. And the default behavior of DF is to remove any station that has only one child.
If it is not present you might need to install a “SingleParentRemover” at the DockController (using “setSingleParentRemover”), this SPR should then not remove this special StackDockStation.
As far as I understand my old code (StackDockStation.add and BubbleStackDockComponent), tabs should be visible. I’ll have to check again in the evening.
I have a StackDockStation with a single dockable and I want to display the single dockable as a tab folder. I used setSingleParentRemover(null); but it’s not working.
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import bibliothek.gui.DockFrontend;
import bibliothek.gui.dock.DefaultDockable;
import bibliothek.gui.dock.SplitDockStation;
import bibliothek.gui.dock.StackDockStation;
import bibliothek.gui.dock.station.split.SplitDockProperty;
public class Test4 {
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame();
JPanel rootPanel = new JPanel();
DockFrontend frontend = new DockFrontend(frame);
frontend.getController().setSingleParentRemover(null);
SplitDockStation root = new SplitDockStation();
frontend.addRoot("root", root);
StackDockStation stack = new StackDockStation();
stack.setTitleText("Stack");
frontend.getController().setSingleParentRemover(null);
DefaultDockable a = new DefaultDockable("a");
frontend.addDockable("dockable1", a);
DefaultDockable b = new DefaultDockable("b");
frontend.addDockable("dockable2", b);
root.drop(stack, SplitDockProperty.EAST);
stack.drop(a);
// stack.drop(b);
rootPanel.setLayout(new GridLayout(1, 1));
rootPanel.add(root, BorderLayout.CENTER);
frame.add(rootPanel, BorderLayout.CENTER);
frame.setBounds(20, 20, 500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Sorry my mistype, setting single parent remover to null ensured that the dockable was not merged into its parents parent station, it did not guarantee that the tab would be visible
Currently single tabs are not implemented. One would need to update the code of StackDockStation to allow that. Sorry, but I’m currently too busy to do that.
You won’t see any effect if you use the EclipseTheme, but you will see a change when using any other theme. Calling “setSingleTabShown” is the correct solution. It’s working in my applications (1.0.8p5d), you are sure you call the method on the right objects? You don’t override the settings later?
(P.S. I’ll upload a new glass-extension ASAP, then you can use the newest version).
control.setTheme(ThemeMap.KEY_ECLIPSE_THEME); // Want to use Eclipse Theme
control.putProperty(SingleTabDecider.SINGLE_TAB_DECIDER, new CustomCommonSingleTabDecider(control));
and
private static class CustomCommonSingleTabDecider extends CommonSingleTabDecider {
//---- Constructors
public CustomCommonSingleTabDecider (CControl control) {
super(control);
}
//---- Methods
@Override
public boolean showSingleTab (DockStation station, Dockable dockable) {
if (dockable.asDockStation() != null) {
return false;
}
if (dockable instanceof CommonDockable) {
final CDockable cdockable= ((CommonDockable) dockable).getDockable();
return cdockable.isSingleTabShown();
}
return false;
}
}
What else do I have to do to support Singe-tabs also in Eclipse theme?
When running the demo application in bibliothek.sizeAndColor Singe-tabs are also supported for Eclipse theme.
I will try to make a test application in the next days.
Actually I have set an EclipseThemeConnector:
// Removes the "empty" border from the DockStations.
control.putProperty(EclipseTheme.THEME_CONNECTOR , new NoBorderThemeConnector(control));
But that does not a lot:
/**
* A theme connector that removes the "empty" border from the {@link bibliothek.gui.DockStation}s.
*/
public class NoBorderThemeConnector extends CommonEclipseThemeConnector {
public NoBorderThemeConnector (CControl control) {
super(control);
}
@Override
public TitleBar getTitleBarKind (Dockable dockable) {
if (dockable.getDockParent() instanceof SplitDockStation) {
return TitleBar.NONE;
}
return super.getTitleBarKind(dockable);
}
}
Hehe, this “does not a lot” is the cause of the problem. “TitleBar.NONE” means “no decorations at all”, and thus no tab at all. This EclipseThemeConnector just overriddes your attempt to make the tab visible. The only way to get the tab is if you return “TitleBar.ECLIPSE”, unfortunatelly this means the border is back.
If you don’t want the border, you’ll have to implement a “TabPainter”. Copy the code of “ArchGradientPainter.FACTORY” and make sure the method “getFullBorder” returns null. You then can install your new TabPainter using the property-key “EclipseTheme.TAB_PAINTER”.
I am working with Preview 5f and the method Dockable.setSingleTabShown is no longer available - I can’t seem to find any information about what it was replaced with. Can you help ?
The method remains, but you may be locking at the wrong class. The method “setSingleTabShown” is declared in “AbstractCDockable” and only available if you use the Common project. Meaning if you use a “DefaultSingleCDockable” or a “DefaultMultipleCDockable”.
In Common (almost) any “dockable” is a subclass of AbstractCDockable, so you will often find source code like “dockable.setSingleTabShown”.
It should not be blank, but that is another problem. Without a SingleTabRemover there is no cleaning up and you will run into problems because more and more old StackDockStations fill up your application.
Instead you should try the SingleTabDecider, somewhat like this:
@Override
public boolean showSingleTab (DockStation station, Dockable dockable) {
return "if dockable should have a tab, then true, else false"
}
});```
My simple example works perfectly, of course ! My full application is still (annoyingly) not working… Weird thing is that the StackDockStation does report it has one tab, but nothing is displayed - even with the DockController property of SingleTabDecider which returns TRUE for every showSingleTab request.
It may have something to do with a PredefinedDockSituation. I’ll look at this again on Monday, thanks for your help so far.
Nz
Ok, I managed to break it (somewhat) below is the code, the issue appears to be in any theme besides the default. After compiling run click the GO button.
Note you can switch between the two tabs.
Switch to the blue and click GO
This should remove the blue panel but instead you cannot switch to the red panel, and both tabs are still visible.
Run again switch to the red and click GO
This should remove the blue panel both tabs are still visible.
nz
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import bibliothek.extension.gui.dock.theme.EclipseTheme;
import bibliothek.extension.gui.dock.theme.FlatTheme;
import bibliothek.extension.gui.dock.theme.flat.FlatTabPane;
import bibliothek.gui.DockFrontend;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.DefaultDockable;
import bibliothek.gui.dock.StackDockStation;
import bibliothek.gui.dock.station.stack.StackDockComponent;
import bibliothek.gui.dock.station.stack.StackDockComponentFactory;
import bibliothek.gui.dock.station.stack.StackDockComponentParent;
import bibliothek.gui.dock.themes.BasicTheme;
public class Test extends JFrame {
private Dockable blue;
public Test() {
DockFrontend frontend = new DockFrontend( this );
final StackDockStation station = new StackDockStation();
this.add( station.getComponent() );
station.add(createDockable( "Red", Color.RED ) , 0);
station.add(blue = createDockable( "Blue", Color.BLUE ) , 1);
frontend.addRoot("aa", station );
this.getContentPane().add(new JButton(new AbstractAction("Go"){
public void actionPerformed(ActionEvent e) {
station.remove(station.indexOf(blue));
//station.drag(blue);
//station.remove(station.indexOf(blue));
}}), BorderLayout.NORTH);
// Choose one of these themes
// 1)
// BasicTheme theme = new FlatTheme();
// theme.setStackDockComponentFactory(new StackDockComponentFactory(){
//
// @Override
// public StackDockComponent create(StackDockComponentParent arg0) {
// // TODO Auto-generated method stub
// return new FlatTabPane(station);
// }});
// frontend.getController().setTheme(theme);
// 2)
// frontend.getController().setTheme(new EclipseTheme());
// 3)
frontend.getController().setTheme(new FlatTheme());
}
public static Dockable createDockable( String title, Color color ){
JPanel panel = new JPanel();
panel.setOpaque( true );
panel.setBackground( color );
return new DefaultDockable( panel, title );
}
public static void main(String[] args) {
Test t = new Test();
t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
t.pack();
t.setBounds(0, 0, 200, 300);
t.setVisible(true);
}
}