Как разместить вкладки над строкой заголовка JInternalFrame в Java Swing?

Я хочу иметь JInternalFrame, который сможет обрабатывать JTabbedPane так же, как Eclipse IDE. Я хочу, чтобы вкладки располагались поверх строки заголовка. У каждой вкладки должна быть своя кнопка закрытия. 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);
    }
}

person user3804927    schedule 13.11.2014    source источник
comment
Вам нужно будет написать свой собственный внешний вид фрейма и делегат...   -  person MadProgrammer    schedule 13.11.2014
comment
После бесчисленных часов изучения LAF это кажется очень сложным для простого требования. Я просмотрел некоторые файлы библиотеки, что вызвало еще большую путаницу. Легко ли узнать о Synth LAF? Однако я не хочу предоставлять LAF для ВСЕХ компонентов. Цитата из Википедии: Однако синтезатор не обеспечивает внешний вид по умолчанию, и компоненты, которые не определены в XML-файле синтезатора, не будут отображаться. Однако можно назначить стиль по умолчанию для всех других виджетов и настроить стили только для некоторых определенных виджетов. - Но это не объясняет, как.   -  person user3804927    schedule 13.11.2014


Ответы (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 — это просто действие, которое также вызывает closeTab(…)

person bugybunny    schedule 13.11.2014
comment
Спасибо, я попробую. - person user3804927; 13.11.2014