JComboBox更改下拉弹出窗口

4

基本上是一个弹出窗口,用于显示JComboBox下面的派生JTextField,如何从下方方向更改JComboBox的弹出窗口的方向,并在顶部/覆盖它显示JComboBox的弹出窗口

编辑:基本JComboBox的代码示例

import java.awt.Dimension;
import javax.swing.*;
import javax.swing.plaf.basic.BasicComboBoxRenderer;

public class HighRowCombo {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new HighRowCombo().makeUI();
            }
        });
    }

    public void makeUI() {
        Object[] data = {"One", "Two with text", "Three with long text, with long text,with long text "};
        JComboBox comboBox = new JComboBox(data);
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.add(comboBox);
        frame.pack();
        BasicComboBoxRenderer renderer = (BasicComboBoxRenderer) comboBox.getRenderer();
        Dimension size = renderer.getPreferredSize();
        size.height += 50;
        renderer.setPreferredSize(size);
        frame.setVisible(true);
    }
}

编辑第二段。 MacOX的代码

import java.awt.*;
import javax.swing.*;

public class TestHighRow {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                new TestHighRow().makeUI();
            }
        });
    }

    public void makeUI() {
        Object[] data = {"One", "Two", "Three"};
        JComboBox comboBox = new JComboBox(data);
        comboBox.setPreferredSize(comboBox.getPreferredSize());
        comboBox.setRenderer(new HighRowRenderer(comboBox.getRenderer()));
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(comboBox);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static class HighRowRenderer implements ListCellRenderer {

        private final ListCellRenderer delegate;
        private int height = -1;

        public HighRowRenderer(ListCellRenderer delegate) {
            this.delegate = delegate;
        }

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            Component component = delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            Dimension size = component.getPreferredSize();
            if (height == -1) {
                height = size.height + 50;
            }
            size.height = height;
            component.setPreferredSize(size);
            if (component instanceof JLabel) {
                ((JLabel) component).setHorizontalTextPosition(JLabel.CENTER);
            }
            return component;
        }
    }
}
4个回答

3

2
在我的系统中,如果 JComboBox 靠近屏幕底部且没有足够的空间向下展开,则它会向上打开。(这是你的意思吗?) 鉴于这个事实,我怀疑改变已定义的行为不会很容易。

我为状态栏功能使用了(JPanel, BorderLayout.SOUTH),其中包含一个JComboBox,我“想要”将JComboBox的弹出窗口嵌入到JFrame中 :-) - mKorbel

2
在Mac OS X上,我收到了以下异常。 显然,com.apple.laf.AquaComboBoxRenderer不是BasicComboBoxRenderer的子类。
补充说明:ClassCastException消失了,并且下面显示了“EDIT 2nd. Code for MacOX”的屏幕截图: enter image description here 在AWT-EventQueue-0线程中发生异常java.lang.ClassCastException: com.apple.laf.AquaComboBoxRenderer无法转换为javax.swing.plaf.basic.BasicComboBoxRenderer 在HighRowCombo.makeUI(HighRowCombo.java:26)处 在HighRowCombo $1.run(HighRowCombo.java:13)处 在java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)处 在java.awt.EventQueue.dispatchEventImpl(EventQueue.java:678)处 在java.awt.EventQueue.access$000(EventQueue.java:86)处 在java.awt.EventQueue $1.run(EventQueue.java:639)处 在java.awt.EventQueue $1.run(EventQueue.java:637)处 在java.security.AccessController.doPrivileged(Native Method)处 在java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)处 在java.awt.EventQueue.dispatchEvent(EventQueue.java:648)处 在java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)处 在java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)处 在java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)处 在java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)处 在java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)处 在java.awt.EventDispatchThread.run(EventDispatchThread.java:122)处

1
(叹气)Mac。- 敢于与众不同。 ;) - Andrew Thompson
据我所知,MetalLookAndFeel始终可用。有时我会使用在这里看到的方法来“借用”另一个L&F中的元素,例如图标。 - trashgod
移除并替换为ListCellRenderer。 - mKorbel
@mKorbel:第二次编辑看起来不错;我已经添加了一张截图,如上所示。 - trashgod

0
package com.example.swing;

import javax.swing.JList;
import javax.swing.ListCellRenderer;
import java.awt.Component;
import java.awt.Dimension;

public class PaddingListCellRenderer<Type> implements ListCellRenderer<Type> {
    private final ListCellRenderer original;
    private final int hpadding;
    private final int vpadding;

    public PaddingListCellRenderer(ListCellRenderer original, int hpadding, int vpadding) {
        this.original = original;
        this.hpadding = hpadding;
        this.vpadding = vpadding;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Component getListCellRendererComponent(JList<? extends Type> list, Type value, int index, boolean isSelected, boolean cellHasFocus) {
        final Component component = original.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        component.setPreferredSize(null);
        final Dimension pref = component.getPreferredSize();
        component.setPreferredSize(new Dimension(pref.width + 2 * hpadding, pref.height + 2 * vpadding));
        return component;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接