【问题标题】:How to place tabs over JInternalFrame title bar in Java Swing?如何在 Java Swing 中的 JInternalFrame 标题栏上放置选项卡?
【发布时间】:2014-11-13 03:24:35
【问题描述】:

我想要一个能够像 Eclipse IDE 一样处理 JTabbedPane 的 JInternalFrame。我希望标签位于标题栏的顶部。每个选项卡都应该有自己的关闭按钮。 InternalFrame 还应该有一个关闭按钮,以便用户可以一次性关闭所有选项卡。

这就是我所拥有的:

这就是我想要的(截图取自 Eclipse IDE):

我不知道如何才能做到这一点。谁能指出我正确的方向?

编辑:

根据对 UI Delegate 的评论,我创建了一个能够删除菜单的 UI 代理子类,但是这样做存在一些问题:

  1. 与普通的 JInternalFrame 相比,它看起来有点有趣,尽管我没有对它做任何事情,只是将“createActionMap”和“add(menuBar)”行注释掉。

  2. 我在库代码中找不到任何地方来指示标题栏和 contentPane 位置的设置方式 - 显然我想移动 contentPane 的位置以与标题栏重叠。

代码如下:

public class MyInternalFrameUI extends BasicInternalFrameUI {

    public MyInternalFrameUI(JInternalFrame b) {
        super(b);
        // TODO Auto-generated constructor stub
    }

    public static ComponentUI createUI(JComponent b)    {
        return new MyInternalFrameUI((JInternalFrame)b);
    }
    
    protected JComponent createNorthPane(JInternalFrame w) {
        titlePane = new MyBasicInternalFrameTitlePane(w);
        return titlePane;
      }
}

public class MyBasicInternalFrameTitlePane extends BasicInternalFrameTitlePane {

    public MyBasicInternalFrameTitlePane(JInternalFrame f) {
        super(f);
    }
    
    protected void installTitlePane() {
        installDefaults();
        installListeners();

        createActions();
        enableActions();
        //createActionMap(); // This method is package protected and not visible

        setLayout(createLayout());

        assembleSystemMenu();
        createButtons();
        addSubComponents();
    }
    
    protected void addSubComponents() {
        //add(menuBar); // Remove this to disable the menu
        add(iconButton);
        add(maxButton);
        add(closeButton);
    }
}

【问题讨论】:

  • 您需要编写自己的内部框架外观委托...
  • 在对 LAF 进行了无数小时的研究之后,对于一个简单的需求来说,这似乎非常复杂。我浏览了一些库文件,这引起了更多的混乱。了解 Synth LAF 最容易吗?但是,我不想为所有组件提供 LAF。来自 wikipedia 的引用:但是,synth 不提供默认外观,并且未在 synth XML 文件中定义的组件将不会被绘制。但是,可以为所有其他小部件分配默认样式,并仅为某些特定小部件自定义样式。 - 但它没有解释如何。

标签: java eclipse swing jtabbedpane jinternalframe


【解决方案1】:

用关闭按钮回答一部分。一个解决方案是自己添加关闭按钮(Swing 中没有内置的选项)。 您必须实现 closeTab(…) 方法,或者更好的解决方案是回调处理程序

protected class CloseTabButton extends JPanel {
    private JLabel            titleLabel;

    protected CloseTabButton(JTabbedPane aTabbedPane,
            final AbstractObservableObjectJPanel<M> aDetailPanel,
            String aTitle, Icon anIcon) {
        setOpaque(false);

        titleLabel = new JLabel(aTitle, anIcon, JLabel.LEFT);
        add(titleLabel);
        ImageIcon closeImage = new ImageIcon(
                CloseTabButton.class.getResource("/images/icon_normal.png"));
        Image img = closeImage.getImage();
        Image newimg = img.getScaledInstance(16, 16,
                java.awt.Image.SCALE_SMOOTH);
        ImageIcon closeIcon = new ImageIcon(newimg);

        ImageIcon closeImageRollover = new ImageIcon(
                CloseTabButton.class.getResource("/images/icon_roll.png"));
        Image imgRoll = closeImageRollover.getImage();
        Image newimgRoll = imgRoll.getScaledInstance(16, 16,
                java.awt.Image.SCALE_SMOOTH);
        ImageIcon closeIconRoll = new ImageIcon(newimgRoll);

        JButton btClose = new JButton(closeIcon);
        btClose.setPreferredSize(new Dimension(15, 15));

        add(btClose);
        btClose.setOpaque(false);
        btClose.setContentAreaFilled(false);
        btClose.setBorderPainted(false);

        btClose.setRolloverIcon(closeIconRoll);
        btClose.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent aE) {
                closeTab(aDetailPanel);
            }
        });
        aTabbedPane.setTabComponentAt(
                aTabbedPane.indexOfComponent(aDetailPanel), this);
    }

    public JLabel getTitleLabel() {
        return titleLabel;
    }
}

要添加键盘快捷键,您可以通过

将它们添加到输入映射中
KeyStroke ctrlW = KeyStroke.getKeyStroke(KeyEvent.VK_W,
        InputEvent.CTRL_DOWN_MASK);
getRootPane()
        .getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
        .put(ctrlW, disposeAction.getValue(Action.NAME));

DisposeAction 只是一个 Action 也调用了closeTab(…)

【讨论】:

  • 谢谢,我会试试这个的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多