Настройка FocusTraversalPolicy для JFrame с помощью GridBagLayout - PullRequest
2 голосов
/ 11 октября 2011

У меня есть JFrame с четырьмя компонентами: три JPanels и JTabbedPane.Две панели имеют выбираемые компоненты и расположены приблизительно в BorderLayout.NORTH и EAST, в то время как JTabbedPane находится приблизительно в CENTER.Вкладки TabbedPane выровнены по нижней части панели.Я говорю примерно, потому что фактическое расположение сделано с GridBagLayout (извините!).

В настоящее время цикл обхода фокуса идет следующим образом:

Current Cycle:  
   1) North JPanel  
   2) East JPanel  
   3) JTabbedPane selected tab  
   4) JTabbedPane selected tab content  

Однако я бы хотел, чтобыбыть:

Desired Cycle:  
   1) North JPanel  
   2) JTabbedPane selected tab content  
   3) JTabbedPane selected tab  
   4) East JPanel  

Я попытался использовать векторную FocusTraversalPolicy, предоставленную Java Focus Guide , но безуспешно: я не смог заставить курсор опуститься в содержимое панели вкладок.

Затем я занялся расширением / изменением других классов FocusTraversalPolicy, но с этим тоже не справился.

Я вполне уверен, что проблема заключается в том, что FocusTraversalPolicy использует расположение компонента на экране для определения цикла компоновки.Технически боковая панель выше на экране, чем центральная панель с вкладками.Я действительно хотел бы изменить это все же.Кто-нибудь еще сталкивался с этим / иметь какое-либо понимание?Спасибо !!

РЕДАКТИРОВАТЬ:

Вот SSCCE с надлежащим кодом макета, демонстрирующим проблему.Просто примечание: проблема не в макете, так как он должен остаться прежним.

package SO;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

public class ssccee7729709{
    JPanel north;
    JPanel north2;
    JPanel east;
    JTabbedPane center;
    JFrame content;

    void initialize() {
        north = new JPanel(new FlowLayout()) {
            {
                this.setBackground(Color.CYAN);
            }
        };
        north.add(new JLabel("Title panel"));

        north2 = new JPanel(new FlowLayout()) {
            {
                this.setBackground(Color.RED);
            }
        };
        north2.add(new JLabel("north2 Panel"));
        north2.add(new JTextField(4));
        north2.add(new JTextField(4));

        east = new JPanel(new GridLayout(3,1)) {
            {
                this.setBackground(Color.BLUE);
            }
        };
        east.add(new JButton("b1"));
        east.add(new JButton("b2"));

        center = new JTabbedPane(JTabbedPane.BOTTOM, JTabbedPane.WRAP_TAB_LAYOUT);
        for (int i = 0; i < 2; i++) {
            JPanel panel = new JPanel(new GridLayout(4,1));
            panel.add(new JLabel("Panel " + i));
            panel.add(new JTextField(6));
            panel.add(new JTextField(6));
            panel.add(new JTextField(6));
            center.addTab("Tab " + i, panel);   
        }

        content = new JFrame();
        content.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        content.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        {
            gbc.fill = GridBagConstraints.BOTH;
            gbc.gridwidth = 4;
            gbc.weightx = 1;
            content.add(north, gbc);
        }
        {
            gbc = new GridBagConstraints();
            gbc.fill = GridBagConstraints.BOTH;
            gbc.anchor = GridBagConstraints.PAGE_START;
            gbc.gridwidth = 1;
            gbc.weightx = 1;
            // gbc.weighty = .1;
            gbc.gridy = 1;
            gbc.gridx = 1;
            content.add(north2, gbc);
        }
        {
            gbc = new GridBagConstraints();
            gbc.fill = GridBagConstraints.BOTH;
            gbc.gridwidth = GridBagConstraints.RELATIVE;
            gbc.gridheight = GridBagConstraints.RELATIVE;
            gbc.weighty = 1;
            gbc.gridy = 2;
            content.add(center, gbc);
        }
        {
            gbc = new GridBagConstraints();
            gbc.fill = GridBagConstraints.VERTICAL;
            gbc.anchor = GridBagConstraints.SOUTHEAST;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.gridx = 3;
            gbc.gridheight = 4;
            content.add(east, gbc);
        }

      content.setVisible(true);
      content.pack();
    }

    public static void main(String args[]) {
        ssccee7729709 so = new ssccee7729709();
        so.initialize();
    }

}

Ответы [ 2 ]

3 голосов
/ 11 октября 2011

Если вы посмотрите на источник для LayoutFocusTraversalPolicy, который является политикой по умолчанию, он в значительной степени просто расширяет SortingFocusTraversalPolicy , который занимает Comparator<? extends Component>.

Вы должны быть в состоянии предоставить свой собственный Comparator, который является внутренним классом и, следовательно, имеет доступ к родительским компонентам, и предоставить соответствующие значения сравнения, глядя на себя и своих родителей.

Вероятно, не помешает проверить источник LayoutComparator , который использует LayoutFocusTraveralPolicy.

2 голосов
/ 12 октября 2011

После клонирования LayoutComparator мне пришлось добавить следующие строки в метод compare:

    ...previous code...
    int zOrder = a.getParent().getComponentZOrder(a) - b.getParent().getComponentZOrder(b);

    /// added these:
    if (a instanceof EastPanel) {
        if (b instanceof JTabbedPane || b instanceof NorthPanel) {
            return -1;
        }
    }
    if (b instanceof EastPanel) {
        if (a instanceof JTabbedPane || a instanceof NorthPanel) {
            return 1;
        }
    }

    if (horizontal) {
        if (leftToRight) {
    ...more code...

Честно говоря, я не знаю, как это работает ... механизм использования compare длязаказ компонентов странный для меня ... но это работает, так что ... ура магия!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...