views:

371

answers:

2

I have two panels that i wish to display to the user. I decided to add them to a JTabbedPane. I also want to allow the user to have a side by side view of them both at the same time. So I added the two panels to my JTabbedPane and then i created a JSplitPanel as such :

    tabs.addTab("Align Image Points", imageControlPanel);
    tabs.addTab("Align Map Points", mapControlPanel);
    JSplitPane splitPane = new JSplitPane(
      JSplitPane.HORIZONTAL_SPLIT, true, imageControlPanel,
      mapControlPanel);
    tabs.addTab("Side by side view", splitPane);

The resulting JTabbedPane only has one tab! When i remove the JSplitPane everything works ok. Two tabs. I then tried simplifying the problem to post here and i came up with this :

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;

public class Test {

    public static void main(String[] args) {
     JFrame f = new JFrame("Test");
     JButton b1 = new JButton("First");
     JButton b2 = new JButton("Second");
     JSplitPane s = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,b1,b2);
     JTabbedPane tabs = new JTabbedPane();
     tabs.addTab("First", b1);
     tabs.addTab("Second", b2);
     tabs.addTab("Both", s);
     f.getContentPane().add(tabs);
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     f.pack();
     f.setVisible(true);
    }

}

This gave me another problem! It displays 3 tabs but the third tab's split pane displays no buttons!

So my question is What is wrong with JSplitPanel? You can't have it display objects that are already displayed in another tab? It makes no sense. Please help me.

(Note: i don't want to duplicate the components that i am about to display as i want them to be the same reference)

+5  A: 

Swing UIs are hierarchical and you can only add a component to the hierarchy once. If you add a component to more than one container you'll get unpredictable results. You are correct to not want to duplicate the components, but you'll need a listener on the JTabbedPane to add and remove each component from the tab or the JSplitView as the selection of the tabs changes.

tabs.addChangeListener( new ChangeListener() {
    public void stateChanged(ChangeEvent e) {
        // Reorganise the display based on the current tab selection.
    }
}
banjollity
+1  A: 

I had the same problem that you had. what I had resolved for this issue, I made the each GUI as MVC pattern(Model-view-controller) that controller knows how to iterative with gui components.

I created a new instance of GUIs(View) on each Tab;however, I injected the same instance of controller for that GUI as constructor parameter since the controller knows how to handle GUI flow and behaviors.

for example,

    GUIView1Controller controller1 = new GUIView1Controller();
    GUIView2Controller controller2 = new GUIView2Controller();

    // Add new instance GUI ; however , use the same instance of controller
    JSplitPane s = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,
                       new GUIView1(controller1), new GUIView2(controller2));

   JTabbedPane tabs = new JTabbedPane();
   tabs.addTab("First", new GUIView1(controller1));
   tabs.addTab("Second", new GUIView2(controller2));
   tabs.addTab("Both",  s );

GUIView1 and GUIView2 will register all GUI listeners to the controller, so the controller will be notified and take an action for the listeners. whatever the GUIView1 on "First" tab is changed, the GUIView1 on "Both" tab also is updated as the same behaviors of the GUIView1 on "First" tab.

The drawback was you have to create a new instance of the GUIView on the tab and JSplitPane; however, the controller can control and share all gui events and behaviors.

I hope it helps.

Tiger.

Tiger
Yes, I like the banjollity idea that you can add "addChangeListener" on the tab, you can only create one instance of GUIView, and based on that change listner, you can switch the gui components back and forth.
Tiger
Thanks for the answer. It seems right (since you solved this problem yourself) but i found another GUI design for my program that is actually better for my case so i wont need to implement this.
Savvas Dalkitsis