How to place tabs over JInternalFrame title bar in Java Swing?

619 views Asked by At

I want to have a JInternalFrame that will be able to handle JTabbedPane much like the Eclipse IDE. I want the tabs to sit on top of the title bar. Each tab should have its own close button. The InternalFrame should also have a close button so that a user can close all the tabs in one go.

This is what I have:

enter image description here

This is what I want to have (screenshot taken from Eclipse IDE):

enter image description here

I don't know how I can achieve this. Can anyone please point me in the right direction?

EDIT:

Based on a comment to look into UI Delegate, I created a UI delegate subclass that is able to remove the menu, but there are some problems with this:

  1. It looks kind of funny in comparison to a normal JInternalFrame, even though I haven't done anything to it but comment out the "createActionMap" and "add(menuBar)" lines.

    enter image description here

  2. I can't find anywhere in the library code to indicate how the title bar and contentPane positions are set - obviously I want to move the position of the contentPane to overlap the title bar.

Here are the codes:

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

There are 1 answers

0
bugybunny On

To answer one part with the close button. A solution is to add the close button yourself (there is no option for that built in Swing). You have to implement the closeTab(…) method or a better solution would be a callback handler

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

To add keyboard shortcuts you can add them to the input map via

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 is just an Action that also calls closeTab(…)