Как оформить товар JComboBox - PullRequest
0 голосов
/ 14 февраля 2020

У меня JComboBox содержит 9 элементов изображения. Как я могу расположить их в 3 * 3?

Я хочу, чтобы мои предметы были расположены таким образом

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

Редактировать:

Спасибо всем за отзывы. Я делаю редактор карт, где я могу собрать элемент карты вместе. Редактор. Намного удобнее обустроить каменную дорогу 3 * 3. Пользователь может легко узнать, какие элементы соответствуют друг другу.

Я не обязательно использую поле со списком. Я также подумал об использовании кнопок, но я думаю, что кнопки будут тратить много места. Потому что у меня будет больше элементов карты в будущем.

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

Во всплывающем окне со списком для отображения элементов используется компонент JList.

Вы можете получить доступ и изменить ориентацию JList для обертывания элементов:

Object child = comboBox.getAccessibleContext().getAccessibleChild(0);
BasicComboPopup popup = (BasicComboPopup)child;
JList list = popup.getList(); 
list.setLayoutOrientation(JList.HORIZONTAL_WRAP);
list.setVisibleRowCount(3);

Это позволит навигация по элементам с помощью клавиш вверх / вниз.

Для поддержки навигации с помощью клавиш влево / вправо необходимо добавить дополнительные связывания клавиш в поле со списком:

InputMap im = comboBox.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
im.put(KeyStroke.getKeyStroke("LEFT"), "selectPrevious");
im.put(KeyStroke.getKeyStroke("RIGHT"), "selectNext");

Однако всплывающее окно основано на ширине самого большого элемента, добавляемого в поле со списком. Это будет проблемой, так как вы не увидите все элементы. Элементы будут прокручиваться при использовании клавиш для навигации, но вы не увидите все 9 элементов одновременно.

Чтобы решить эту проблему, воспользуйтесь Всплывающее окно со списком . Он имеет функции, которые позволяют вам контролировать размер / поведение всплывающего окна. Вы бы использовали:

BoundsPopupMenuListener listener = new BoundsPopupMenuListener(true, false);
comboBox.addPopupMenuListener( listener );
0 голосов
/ 14 февраля 2020

Можно сделать это, назначив JComboBox пользовательский интерфейс. Однако этот пользовательский интерфейс, по крайней мере, в моем случае, является беспорядком, поэтому использует его только в качестве обходного пути и четко помечает его как таковой с помощью встроенной документации. Следующий код сделан для Swing Look и Feel (Metal) по умолчанию. Если вы хотите использовать другой L & F, вам нужно заменить класс, пользовательский интерфейс которого расширяется, и, возможно, выполнить некоторые другие настройки. Это усложнит спецификацию распространения c L & F (может заставить вас использовать рефлексию и делегирование). (Если вы также хотите центрировать свои изображения, см. этот ответ .) Код: (Извините за странные комментарии, не знаю, что случилось с моим затмением.) Чтобы установить пользовательский интерфейс:

comboBox.setUI(new WrapComboBoxUI(3)); // 3 columns

Исходный код WrapComboBoxUI:

import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.plaf.metal.MetalComboBoxUI;

public class WrapComboBoxUI extends MetalComboBoxUI {

    private int columnCount;

    public WrapComboBoxUI() {
        this(0);
    }

    /**
     * @param columnCount
     *            the amount of items to render on one row. <br/>
     *          A value of 0 or less will cause the UI to fit as many items
     *            into one row as possible.
     */
    public WrapComboBoxUI(int columnCount) {
        this.columnCount = columnCount;
    }

    public static ComponentUI createUI(JComponent c) {
        return new WrapComboBoxUI();
    }

    @Override
    protected ComboPopup createPopup() {
        ComboPopup created = super.createPopup();
        try {
            if (created instanceof JPopupMenu) {
                JPopupMenu popup = (JPopupMenu) created;
                JScrollPane scroll = (JScrollPane) popup.getComponent(0);
                JList<?> elementList = (JList<?>) scroll.getViewport().getView();
                elementList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
                elementList.setVisibleRowCount(-1);

                new Thread() {
                    @Override
                    public void run() {
                        while (true) {
                            try {
                                int fixedWidth = -1;
                                if (columnCount > 0) {
                                    int width = elementList.getWidth() - elementList.getInsets().left - elementList.getInsets().right;
                                    fixedWidth = width / columnCount;
                                }
                                boolean changed = false;
                                if (fixedWidth < 0 && elementList.getFixedCellWidth() >= 0 || fixedWidth >= 0 && elementList.getFixedCellWidth() < 0) {
                                    // if changed from not fixed to fixed or
                                    // other way around
                                    changed = true;
                                } else if (fixedWidth > 0 && fixedWidth - elementList.getFixedCellWidth() > 1) {
                                    // if width itself changed, ignoring slight
                                    // changes
                                    changed = true;
                                }
                                final int width = fixedWidth;

                                // no need to loop again before this is done, so
                                // we wait
                                if (changed)
                                    SwingUtilities.invokeAndWait(() -> elementList.setFixedCellWidth(width));

                                sleep(100);
                            } catch (Throwable e) {
                                // ignored
                            }
                        }
                    };
                }.start();
            }
        } catch (Throwable e) {
            System.err.println("Failed to customize ComboBoxUI:");
            e.printStackTrace();
        }
        return created;
    }
}
...