【问题标题】:Putting multiple JPanels inside a JTabbed pane将多个 JPanel 放入 JTabbedpane
【发布时间】:2013-11-05 22:58:44
【问题描述】:

我环顾四周,也尝试将多个面板添加到 JTabbedPane。

我的问题是:是否可以将相同的 Jpanel 添加到多个 TabbedPanes。我尝试过的所有方法似乎都无法正常工作。这就是它的工作原理。

public MainGUI() {

  JMenuBar menuBar = new JMenuBar();
  setJMenuBar(menuBar);

  JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
  getContentPane().add(tabbedPane, BorderLayout.CENTER);

  JEditorPane instructionalEditorPane = new JEditorPane();
  tabbedPane.addTab("Instructional", instructionalEditorPane);

  JPanel codePanel = new JPanel();
  JPanel drawPanel = new JPanel();

  JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, codePanel, drawPanel);
  splitPane.setResizeWeight(0.75);

  tabbedPane.addTab("Code Panel", splitPane);

  JEditorPane unifiedInstPane = new JEditorPane();
  JPanel unifiedCodePanel = new JPanel();
  JPanel unifiedDrawPanel = new JPanel();
  JSplitPane unifiedSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, unifiedCodePanel, unifiedDrawPanel);
  unifiedSplitPane.setResizeWeight(0.75);

  JSplitPane unifiedPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT,unifiedInstPane, unifiedSplitPane);
  unifiedPanel.setResizeWeight(0.40);
  tabbedPane.addTab("Unified Tab", unifiedPanel);
}

我想做的只是将指令编辑器窗格和 splitPane 添加到多个 tabbedPanes,但是当我这样做时,我会松开原始的 Individual tabbedPanes。如果必须这样做,我可以这样做,但我必须同时写信给统一的 InstPane 和指令编辑器以保持更新。我还必须对嵌入了 codePanel 和 drawPanel 的 2 个 splitPanel 执行此操作。这将使所有面板保持同步变得更加困难。

有什么建议吗?

【问题讨论】:

    标签: java swing jtabbedpane jsplitpane


    【解决方案1】:

    "Is it possible to add the same Jpanel to multiple TabbedPanes." -- 没有。您一次只能将一个组件添加到一个容器中。您的 JPanel 应该共享 模型,但使用独特的组件。该模型可能是您创建的非 GUI 类。

    例如,这是我的建议的非常简单呈现:

    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    
    import javax.swing.*;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.PlainDocument;
    
    public class MainGui2 extends JPanel {
       private static final int TAB_COUNT = 3;
       private JTabbedPane tabbedPane = new JTabbedPane();
       private PlainDocument doc = new PlainDocument();
       private Action btnAction = new ButtonAction("Button");
    
       public MainGui2() {
          for (int i = 0; i < TAB_COUNT; i++) {
             tabbedPane.add("Tab " + (i + 1), createPanel(doc, btnAction));
          }
          setLayout(new BorderLayout());
          add(tabbedPane);
       }
    
       private JPanel createPanel(PlainDocument doc, Action action) {
          JTextArea textArea = new JTextArea(doc);
          textArea.setColumns(40);
          textArea.setRows(20);          
    
          JPanel panel = new JPanel();
          panel.add(new JScrollPane(textArea));
          panel.add(new JButton(action));
          return panel;
       }
    
       private class ButtonAction extends AbstractAction {
          public ButtonAction(String title) {
             super(title);
          }
    
          @Override
          public void actionPerformed(ActionEvent evt) {
             try {
                String text = "Button Pressed!\n";
                doc.insertString(doc.getLength(), text, null);
             } catch (BadLocationException e) {
                e.printStackTrace();
             }
          }
       }
    
       private static void createAndShowGui() {
          JFrame frame = new JFrame("MainGui2");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.getContentPane().add(new MainGui2());
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    

    最好创建一个正式的模型类,将其注入每个视图、每个选项卡式窗格的各个窗格中。


    编辑
    您在评论中声明:

    是的,我可以通过调用实例来解决这个问题,但是我又回到了我原来的问题,即必须调用每个实例以影响所有面板中的更改。比如说我有一个绘图面板,我需要调用 repaint(),我必须调用 2 个不同的实例来更新两个 tabbedPanes。有没有办法解决?

    是的,解决方案是使用 MVC 或模型-视图-控制结构。您的模型包含您的整体程序逻辑,视图是用户看到的内容,并且控件在两者之间进行交互。

    考虑让您的模型通知控件或视图其已更改,然后这会刺激重新绘制所有观察者视图。

    【讨论】:

    • 我可以让它为教学面板和 codePanel 工作,但 drawPanel 呢。我将如何为此实现模型? (还是我跑题了?)
    • @jbolt:你需要从你的 drawPanel 中提取支持它的非 GUI 逻辑,并将它放在它自己的类中,可能称为 DrawPanelModel。然后给你的 DrawPanel 类一个setModel(...) 方法,让你所有的 DrawPanel 实例共享同一个模型。
    • 有趣的想法。从来没有想过这样做。让我看看我能想出什么。敬请期待...
    • 是的,这就是我刚刚实现的。我有一个工作模型,但是如何调用 repaint() 来更新选项卡式窗口。我在调用模型时遇到错误,抱怨对非静态方法进行静态调用
    • @jbolt:然后修复这个错误——不要调用类,而是调用实例。您应该知道如何解决这些问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 2013-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多