【问题标题】:What's wrong with JSplitPanel (or JTabbedPane)?JSplitPanel(或 JTabbedPane)有什么问题?
【发布时间】:2009-07-11 14:24:05
【问题描述】:

我有两个希望向用户显示的面板。我决定将它们添加到 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 有什么问题?您不能让它显示已经在另一个选项卡中显示的对象吗?这没有道理。请帮帮我。

(注意:我不想复制即将显示的组件,因为我希望它们是相同的参考)

【问题讨论】:

    标签: java swing jtabbedpane


    【解决方案1】:

    Swing UI 是分层的,您只能将一个组件添加到层次结构中一次。如果您将一个组件添加到多个容器中,您将得到不可预知的结果。您不想复制组件是正确的,但您需要在 JTabbedPane 上安装一个侦听器,以便在选项卡的选择发生变化时从选项卡或 JSplitView 添加和删除每个组件。

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

    【讨论】:

      【解决方案2】:

      我遇到了和你一样的问题。我已经解决了这个问题,我将每个 GUI 制作为 MVC 模式(模型-视图-控制器),控制器知道如何使用 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 侦听器注册到控制器,因此控制器将收到通知并为侦听器执行操作。无论“First”选项卡上的 GUIView1 发生什么变化,“Both”选项卡上的 GUIView1 也会更新为与“First”选项卡上的 GUIView1 相同的行为。

      缺点是您必须在选项卡和 JSplitPane 上创建 GUIView 的新实例;但是,控制器可以控制和共享所有 gui 事件和行为。

      我希望它有所帮助。

      老虎。

      【讨论】:

      • 是的,我喜欢这样的想法,您可以在选项卡上添加“addChangeListener”,您只能创建一个 GUIView 实例,并且基于该更改侦听器,您可以切换回 gui 组件并第四。
      • 感谢您的回答。看起来是对的(因为你自己解决了这个问题),但我为我的程序找到了另一个 GUI 设计,它实际上更适合我的情况,所以我不需要实现这个。
      猜你喜欢
      • 2023-03-16
      • 1970-01-01
      • 2021-04-06
      • 2013-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-25
      • 1970-01-01
      相关资源
      最近更新 更多