-1

TabbedComponent(extending JTabbedPane)を変数として格納するMainクラスがあります。別のクラス(ToolbarComponent(extending JMenuBar)も、メインクラス内に変数として格納されています。

ツールバーのユーザーイベントが発生すると、親クラス(main)を呼び出して、TabbedComponentオブジェクトを取得し、メソッドを呼び出して新しいタブを作成します。これはすべて正常に機能します。

私の問題は、マウスでtaをクリックしようとしても、何も変わらないということです。こんなにシンプルなもののためにMouseAdapterのリスナーは必要ないと確信していますが、必要に応じてリスナーを追加します。

以下は、この問題に関連するクラスの簡略版です。

パブリッククラスExampleClassはJFrameを拡張します{

private TabbedBrowserPaneComponent cTabbedBrowserPane;

public ExampleClass() {
    super("");

    // Set up Components
    this.cTabbedBrowserPane = new TabbedBrowserPaneComponent(this);

    // Set up behaviour
    setSize(500, 300);
    setVisible(true);
}

/**
 * @return the cTabbedBrowserPane
 */
public TabbedBrowserPaneComponent getTabbedBrowserPane() {
    return cTabbedBrowserPane;
}


/**
 * @param cTabbedBrowserPane the cTabbedBrowserPane to set
 */
public void setTabbedBrowserPane(TabbedBrowserPaneComponent cTabbedBrowserPane) {
    this.cTabbedBrowserPane = cTabbedBrowserPane;
}

}

public class TabbedBrowserPaneComponent extends JTabbedPane {

// Parent class of the component
private JFrame parent = null;

public TabbedBrowserPaneComponent(JFrame parent) {
    super();
    setParent(parent);

    // Add an initial pane
    createNewTab();
    parent.getContentPane().add(this);
}

public void createNewTab() {
    JPanel panel = new JPanel(new BorderLayout());
    panel.add(new JScrollPane(), BorderLayout.CENTER);
    this.addTab("Tab " + this.getTabCount(), panel);
}

/**
 * @return the parent
 */
public JFrame getParent() {
    return parent;
}

/**
 * @param parent the parent to set
 */
public void setParent(JFrame parent) {
    this.parent = parent;
}
}

新しいタブを作成するには、ToolBarComponentのリスナーは次のように呼び出します

public class CreateNewTabAction extends AbstractAction {

// Parent
private JMenu parent;

public CreateNewTabAction(JMenu parent) {
    super();
    this.setParent(parent);

    // Values for the tab
    putValue(Action.NAME, "New Tab");
}

@Override
public void actionPerformed(ActionEvent e) {
    ExampleClass.class.cast((parent.getParent().getParent())).getTabbedBrowserPane().createNewTab();
}

/**
 * @return the parent
 */
public JMenu getParent() {
    return parent;
}

/**
 * @param parent the parent to set
 */
public void setParent(JMenu parent) {
    this.parent = parent;
}
}

これは本当に単純に私が行方不明になっていることですか?

4

1 に答える 1

3

あなたのコードは、デザインの大幅な欠如を示しています。申し訳ありません(私は意地悪をしようとはしていませんが、この種の動作を元に戻すために3年間の大部分を費やしたので、厄介なひきつりを与えます)。

問題は、コンポーネントが実際にどこに追加されているかを判別するために使用されるgetParent方法であるオーバーライドを行っていることです。Componentこれにより、システムの内部動作に問題が発生します。

タブコンポーネントに親フレームを指定する必要はありません。何らかの理由で本当に親フレームにアクセスする必要がある場合は、を使用することを検討してSwingUtilities.getWindowAncestorください。フレーム内のタブに機能を提供することだけを計画している場合はinterface、タブとコントローラー/エンジンの間のコントラクトを確立できるを作成します。

私を始めさせないでくださいAction...

実際に何を達成しようとしているのかわかりませんが、ブラウザタブやメインフレームへの参照を渡す必要はまったくありません。プログラムの要素を渡すと、そこで機能するために親に関する多くの情報を知る必要がなくなります。また、コンポーネントの柔軟性と再利用性が大幅に制限されます。

以下でinterfaceは、例内のさまざまなビューとコントロール間のコントラクトを提供する単純な\controllerを使用します。さまざまな要素のどれも、実際にはもっと多くを知る必要はありません...

public class ExampleClass {

    public static void main(String[] args) {
        new ExampleClass();
    }

    public ExampleClass() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                BrowserPane browserPane = new BrowserPane();
                CreateNewTabAction createNewTabAction = new CreateNewTabAction(browserPane);

                JMenu mnu = new JMenu("Stuff");
                mnu.add(createNewTabAction);

                JMenuBar mb = new JMenuBar();
                mb.add(mnu);

                JToolBar tb = new JToolBar();
                tb.add(createNewTabAction);

                JFrame frame = new JFrame();
                frame.setJMenuBar(mb);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(browserPane);
                frame.add(tb, BorderLayout.NORTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public interface TabController {

        public void createNewTab();
    }

    public class BrowserPane extends JPanel implements TabController {

        private TabbedBrowserPaneComponent cTabbedBrowserPane;

        public BrowserPane() {
            setLayout(new BorderLayout());
            // Set up Components
            this.cTabbedBrowserPane = new TabbedBrowserPaneComponent();
            add(cTabbedBrowserPane);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        public void createNewTab() {

            cTabbedBrowserPane.createNewTab();

        }
    }

    public class TabbedBrowserPaneComponent extends JTabbedPane {

        public TabbedBrowserPaneComponent() {
            super();
            createNewTab();
        }

        public void createNewTab() {
            JPanel panel = new JPanel(new BorderLayout());
            panel.add(new JScrollPane(), BorderLayout.CENTER);
            this.addTab("Tab " + this.getTabCount(), panel);
        }
    }

    public class CreateNewTabAction extends AbstractAction {

        private TabController controller;

        public CreateNewTabAction(TabController controller) {
            super();
            this.controller = controller;
            putValue(Action.NAME, "New Tab");
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            getController().createNewTab();
        }

        /**
         * @return the parent
         */
        public TabController getController() {
            return controller;
        }
    }
}
于 2012-12-14T03:24:29.503 に答える