如何布置JComboBox物品

问题描述 投票:0回答:2

我有一个JComboBox包含9个图像项。如何将它们排列为3 * 3?

“”

“”

我希望我的物品像这样安排

“”

我已经用Google搜索了好几天,但是我不知道这个问题的关键字是什么。任何建议表示赞赏。感谢您阅读我的问题。

编辑:

感谢大家的反馈。我正在制作一个地图编辑器,可以在其中放置地图元素。The editor. 布置3 * 3的石路更为直观。用户可以轻松知道哪些元素相互匹配。

我不一定要使用组合框。我也考虑过使用按钮,但是我认为按钮会浪费一小块空间。因为将来我会有更多的地图元素。

java swing user-interface jcombobox
2个回答
1
投票

组合框的弹出窗口使用JList组件显示项目。

您可以访问和更改JList的方向以包装项目:

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

这将允许您使用上/下键在项目之间导航。

为了支持使用向左/向右键的导航,您需要在组合框中添加其他Key Bindings

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

但是,弹出窗口基于添加到组合框中的最大项目的宽度。这将是一个问题,因为您将看不到所有项目。当您使用键进行导航时,这些项目将滚动,但是您一次不会看到全部9个项目。

要解决此问题,请签出Combo Box Popup。它具有允许您控制弹出窗口的大小/行为的功能。您将使用:

BoundsPopupMenuListener listener = new BoundsPopupMenuListener(true, false);
comboBox.addPopupMenuListener( listener );

0
投票

可能通过为JComboBox提供自定义UI来执行此操作。但是,至少就我而言,该UI一片混乱,因此请使用内联文档仅将其用作解决方法,并明确地将其标记为这样。以下代码用于默认的Swing外观(金属)。如果要使用其他L&F,则需要交换自定义UI正在扩展的类,并可能需要进行其他一些调整。对于特定于发行版的L&F,这将变得很棘手(可能会迫使您使用反射和委派)。((如果您还想将图像居中,请参阅this answer。]代码:(对不起的注释包装,很抱歉,我的日食出了什么问题。)设置用户界面:

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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.