【问题标题】:Dynamically size the width of a JComboBox to avoid '...' in all scenarios动态调整 JComboBox 的宽度以避免在所有场景中出现“...”
【发布时间】:2019-07-26 17:23:44
【问题描述】:

以下示例将 JComboBox 放置在 Frame 上并加载 5 个项目。

应用程序运行时,显示组合框,看到的是“Long Item...”

在不知道实际激活组合框的情况下,用户不知道实际可见的记录。

请记住,这实际上是一个动态加载的 JComboBox。仅在示例中使用硬编码值。结果,最长字符串的长度直到运行时才可用。

import javax.swing.JComboBox;
import javax.swing.JFrame;
public class JComboBoxTestLength  {
    JFrame f;
    JComboBoxTestLength (){
        f=new JFrame("ComboBox Example");
        String country[]={"Long Item 5","Long Item 2","Long Item 1","Long Item 8","Long Item 4"};
        JComboBox cb=new JComboBox(country);
        cb.setBounds(50, 50,90,20);
        f.add(cb);
        f.setLayout(null);
        f.setSize(400,500);
        f.setVisible(true);
    }
    public static void main(String[] args) {
        new JComboBoxTestLength ();
    }
}

一些线程表示要避免使用 setPreferredSize()。

虽然我可以将 setBounds() 值设置为足够长,但希望它看起来美观,并希望根据最长的字符串 + 2 或类似的东西来计算它。

是否可以计算 JComboBox 的宽度以避免看到任何文本出现“...”?

【问题讨论】:

  • jComboBox1.setToolTipText(jComboBox1.getSelectedItem().toString());
  • “动态调整 JComboBox 的宽度以避免在所有场景中出现'...'” 让布局来处理它。哦,f.setLayout(null);不要 那样做。 Java GUI 必须在不同的操作系统、屏幕尺寸、屏幕分辨率等上工作,在不同的语言环境中使用不同的 PLAF。因此,它们不利于像素完美布局。而是使用布局管理器,或 combinations of them 以及 white space 的布局填充和边框。
  • 我不确定为什么(以及谁做了)我的回答被否决了。这是您当前问题的解决方案。除了最佳实践,解决方案可以解决您的问题:github.com/fiveobjects/reference/blob/master/java/misc/src/main/…
  • @fiveelements 您想将此评论添加到您的答案中吗?我不是反对者,但这可能是由于解决方案的质量。 “解决方案有效”是必不可少的,但还不够。赞成/反对投票反映了答案/问题的质量。在这种情况下,我认为您提出的解决方案质量不高。
  • 我尝试了来自 Fiveelements 的代码,但它抛出了 StackOverflowError。尽管组合框足够宽,但它看起来异常宽。我从答案中收集到的是没有直接的方法,需要与布局管理器一起调整自身大小。

标签: java swing layout-manager jcombobox null-layout-manager


【解决方案1】:

正如Andrew Thomson 所评论的那样,使用Layout managers 来实现所需的布局。
在这种情况下,用使用 FlowLayoutJPanel 包装组合可以为您完成工作:

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class JComboBoxTestLength  {

    JComboBoxTestLength (){
        JFrame f=new JFrame("ComboBox Example");
        String country[]={"Long Item 5","Long Item 2","Long Item 1","Long Item 8","Long Item 4"};
        JComboBox<String> cb=new JComboBox<>(country);
        JPanel comboPane = new JPanel(); //uses FlowLayout by default
        comboPane.add(cb);
        f.add(cb); //JFrame content pane uses BorderLayout by default 
        f.pack();
        f.setVisible(true);
    }
    public static void main(String[] args) {
        new JComboBoxTestLength ();
    }
}

【讨论】:

  • 这很好用,能够添加标签和左对齐,它看起来仍然不错。随着额外组件的添加,将不得不更多地使用布局管理器以确保其美观。
  • 很高兴它有帮助。如果您发布新问题,请给我留言,我会尽力帮助您。
【解决方案2】:

这是一个更完整的示例,它使用 FlowLayout 正确定位和调整 20 个组合框的大小。组合框的宽度仅在初始化时才知道,但每个组合框的宽度都足以显示其包含的最长字符串。

如果要在以后才填充组合时建议大小,请为组合提供预期的最长字符串并调用setPrototypeDisplayValue(E),然后在打包 GUI 后设置一个空模型。

这是生成如上所示视图的代码。

import java.awt.*;
import java.util.Random;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class BigComboSize {

    private JComponent ui = null;
    public final static String INPUT = "Lorem ipsum dolor sit amet, ex mea nostro dictas, duo ludus quando perpetua et. Vis wisi delicata referrentur ex, nec sonet verear molestie eu, commodo impetus ea sit. Mea an audiam debitis similique. No fastidii facilisi democritum est.";
    public final static String[] INPUT_ARRAY = INPUT.split(" ");
    Random random = new Random();

    BigComboSize() {
        initUI();
    }

    public final void initUI() {
        if (ui!=null) return;

        ui = new JPanel(new BorderLayout(4,4));
        ui.setBorder(new EmptyBorder(4,4,4,4));

        JPanel comboPanel = new JPanel();
        comboPanel.setPreferredSize(new Dimension(800,150));
        ui.add(comboPanel);
        for (int ii=0; ii<20; ii++) {
            String[] strings = {
                getRandomString(), getRandomString(), getRandomString()
            };
            JComboBox<String> combo = new JComboBox<>(strings);
            comboPanel.add(combo);
        }

        JTextArea inputArea = new JTextArea(INPUT, 3, 100);
        inputArea.setEnabled(false);
        inputArea.setLineWrap(true);
        inputArea.setWrapStyleWord(true);
        ui.add(new JScrollPane(inputArea), BorderLayout.PAGE_END);
    }

    private String getRandomString() {
        StringBuilder sb = new StringBuilder();

        int sttIndex = random.nextInt(INPUT_ARRAY.length-7);
        int endIndex = sttIndex + 1 + random.nextInt(6);
        for (int ii=sttIndex; ii<endIndex; ii++) {
            sb.append(INPUT_ARRAY[ii]);
            sb.append(" ");
        }

        return sb.toString().trim();
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = () -> {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception useDefault) {
            }
            BigComboSize o = new BigComboSize();

            JFrame f = new JFrame(o.getClass().getSimpleName());
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setLocationByPlatform(true);

            f.setContentPane(o.getUI());
            f.pack();
            f.setMinimumSize(f.getSize());

            f.setVisible(true);
        };
        SwingUtilities.invokeLater(r);
    }
}

【讨论】:

  • 我不知道setPrototypeDisplayValue。学到了新东西,谢谢!
  • 很好的例子,谢谢。将不得不更仔细地查看代码,以确保我了解错综复杂的内容。
猜你喜欢
  • 2013-03-24
  • 1970-01-01
  • 2015-01-27
  • 1970-01-01
  • 1970-01-01
  • 2014-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多