Что не так с JSplitPanel (или JTabbedPane)? - PullRequest
2 голосов
/ 11 июля 2009

У меня есть две панели, которые я хочу показать пользователю. Я решил добавить их в JTabbedPane. Я также хочу позволить пользователю одновременно видеть их обоих. Поэтому я добавил две панели в свой JTabbedPane, а затем создал JSplitPanel как таковой:

    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);

Полученный JTabbedPane имеет только одну вкладку! Когда я удаляю JSplitPane все работает нормально. Две вкладки. Затем я попытался упростить задачу, чтобы опубликовать здесь, и я придумал это:

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);
    }

}

Это дало мне еще одну проблему! Он отображает 3 вкладки, но на разделенной панели третьей вкладки нет кнопок!

Итак, мой вопрос: что не так с JSplitPanel? Вы не можете отображать объекты, которые уже отображаются на другой вкладке? Это не имеет никакого смысла. Пожалуйста, помогите мне.

(Примечание: я не хочу дублировать компоненты, которые я собираюсь отобразить, поскольку хочу, чтобы они были одинаковыми ссылками)

Ответы [ 2 ]

6 голосов
/ 11 июля 2009

Пользовательские интерфейсы Swing являются иерархическими, и вы можете добавить компонент в иерархию только один раз. Если вы добавите компонент в несколько контейнеров, вы получите непредсказуемые результаты. Вы не хотите дублировать компоненты, но вам потребуется прослушиватель на JTabbedPane для добавления и удаления каждого компонента из вкладки или JSplitView при изменении выбора вкладок.

tabs.addChangeListener( new ChangeListener() {
    public void stateChanged(ChangeEvent e) {
        // Reorganise the display based on the current tab selection.
    }
}
1 голос
/ 11 июля 2009

У меня была та же проблема, что и у вас. что я решил для этой проблемы, я сделал каждый GUI как шаблон MVC (Model-view-controller), который контроллер знает, как выполнять итерацию с компонентами GUI.

Я создал новый экземпляр GUI (представление) на каждой вкладке, однако я ввел один и тот же экземпляр контроллера для этого GUI в качестве параметра конструктора, поскольку контроллер знает, как обрабатывать поток и поведение GUI.

например,

    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 и GUIView2 зарегистрируют всех слушателей GUI на контроллере, поэтому контроллер будет уведомлен и предпримет действия для слушателей. независимо от того, изменяется ли GUIView1 на вкладке «Первый», GUIView1 на вкладке «Оба» также обновляется в соответствии с поведением GUIView1 на вкладке «Первый».

Недостатком было то, что вы должны создать новый экземпляр GUIView на вкладке и JSplitPane; однако контроллер может контролировать и делиться всеми событиями и поведением графического интерфейса.

Надеюсь, это поможет.

Tiger.

...