gpt4 book ai didi

java - 如果显示区域太小,带有工具提示的 JComboBox,同时保持外观和感觉

转载 作者:行者123 更新时间:2023-11-30 07:39:45 25 4
gpt4 key购买 nike

我正在创建一个组合框,当显示区域太小而无法显示所选项目的所有文本时,它会显示工具提示。

目前我的解决方案存在的问题:

  • 它不会保持常规组合框的外观。
  • 我不确定我的解决方案是否适用于 Windows 系统以外的系统。我想到的是通过设置断点,看看我需要覆盖什么以获得适当的大小:我覆盖了 DefaultListCellRenderer.setBounds 来做到这一点。

我在底部包含的小 MCVE 显示了我的想法。它显示了四个组合框。第一个和第三个是常规的未调整的 JComboBox 实例,第二个和第四个是调整过的组合框,用于在显示区域对于文本来说太小时显示工具提示。第一和第二启用,第三和第四禁用;这是为了更好地展示外观和感觉上的差异。快照:

enter image description here

当显示区域变得太小时,如何保持常规组合框的外观和工具提示?我走在正确的道路上吗?如果是,我还需要做些什么?如果不是,我应该怎么做?


import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ComboWithTooltip {
public static void main(String[] args) {
try {
// On my system: "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName( ));
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
System.err.println("Can't set look and feel");
return;
}
EventQueue.invokeLater (
new Runnable() {
@Override
public void run() {
buildFrame().setVisible(true);
}
}
);
}

static JFrame buildFrame() {
JPanel contentPane = new JPanel();
BoxLayout layout = new BoxLayout(contentPane, BoxLayout.Y_AXIS);
contentPane.setLayout(layout);
contentPane.add(Box.createVerticalStrut(25));
contentPane.add(createDefaultCombo(true/*enabled*/));
contentPane.add(Box.createVerticalStrut(25));
contentPane.add(createTweakedCombo(true/*enabled*/));
contentPane.add(Box.createVerticalStrut(25));
contentPane.add(createDefaultCombo(false/*enabled*/));
contentPane.add(Box.createVerticalStrut(25));
contentPane.add(createTweakedCombo(false/*enabled*/));
contentPane.add(Box.createVerticalStrut(25));

JFrame frame = new JFrame();
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
return frame;
}

private final static String[] items = new String[]{ "Long text 1234444444444444444444444", "Some more of that long texttttttttttttttttttttt", "The longer the text, the harder to read it becomessssssssssssssssssssssssssssssssssssssss" };

@SuppressWarnings("serial")
private static JComboBox<String> createDefaultCombo(boolean enabled) {
JComboBox<String> comboBoxDefault = new JComboBox<String>(items) {
@Override
public Dimension getPreferredSize() {
return new Dimension(100,25); // intentionally too small
}
};
comboBoxDefault.setEnabled(enabled);
return comboBoxDefault;
}

@SuppressWarnings("serial")
private static class JComboBoxTweaked extends JComboBox<String> {
public JComboBoxTweaked(String[] items) {
super(items);

setRenderer (
new DefaultListCellRenderer() {
@Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds( x, y, width, height );

if( width != 0 ) {
if( getPreferredSize( ).width > getSize( ).width )
JComboBoxTweaked.this.setToolTipText( getText( ) );
else
JComboBoxTweaked.this.setToolTipText( null );
}
}
}
);
}

@Override
public Dimension getPreferredSize() {
return new Dimension(100,25); // intentionally too small
}
};

private static JComboBox<String> createTweakedCombo(boolean enabled) {
JComboBox<String> comboBoxTweaked = new JComboBoxTweaked(items);
comboBoxTweaked.setEnabled(enabled);
return comboBoxTweaked;
}
}

最佳答案

此处的解决方案:提供对标准 L&F 渲染器的委托(delegate)。这是代码:

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;
import java.util.Objects;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ComboWithTooltip {
public static void main(String[] args) {
try {
// On my system: "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
System.err.println("Can't set look and feel");
return;
}
EventQueue.invokeLater(
new Runnable() {
@Override
public void run() {
buildFrame().setVisible(true);
}
});
}

static JFrame buildFrame() {
JPanel contentPane = new JPanel();
BoxLayout layout = new BoxLayout(contentPane, BoxLayout.Y_AXIS);
contentPane.setLayout(layout);
contentPane.add(Box.createVerticalStrut(25));
contentPane.add(createDefaultCombo(true/* enabled */));
contentPane.add(Box.createVerticalStrut(25));
contentPane.add(createTweakedCombo(true/* enabled */));
contentPane.add(Box.createVerticalStrut(25));
contentPane.add(createDefaultCombo(false/* enabled */));
contentPane.add(Box.createVerticalStrut(25));
contentPane.add(createTweakedCombo(false/* enabled */));
contentPane.add(Box.createVerticalStrut(25));

JFrame frame = new JFrame();
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
return frame;
}

private final static String[] items =
new String[] {"Long text 1234444444444444444444444", "Some more of that long texttttttttttttttttttttt",
"The longer the text, the harder to read it becomessssssssssssssssssssssssssssssssssssssss"};

@SuppressWarnings("serial")
private static JComboBox<String> createDefaultCombo(boolean enabled) {
JComboBox<String> comboBoxDefault = new JComboBox<String>(items) {
@Override
public Dimension getPreferredSize() {
return new Dimension(100, 25); // intentionally too small
}
};
comboBoxDefault.setEnabled(enabled);
return comboBoxDefault;
}

@SuppressWarnings("serial")
private static class JComboBoxTweaked extends JComboBox<String> {
public JComboBoxTweaked(String[] items) {
super(items);

setRenderer(new DelegateComboBoxRenderer<>(getRenderer(), this));
}

@Override
public Dimension getPreferredSize() {
return new Dimension(100, 25); // intentionally too small
}
};

private static class DelegateComboBoxRenderer<E> extends JPanel implements ListCellRenderer<E> {

private final ListCellRenderer<E> delegate;

private final JComboBox<?> combo;
private String lastText;

/**
* @param delegate
*/
public DelegateComboBoxRenderer(ListCellRenderer<E> delegate, JComboBox<?> combo) {
setLayout(new GridLayout(1, 1));
setOpaque(true);
this.delegate = delegate;
this.combo = combo;

}

@Override
public Component getListCellRendererComponent(JList<? extends E> list, E value, int index, boolean isSelected,
boolean cellHasFocus) {
removeAll();
Component c = delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
add(c);
if (c instanceof JLabel) {
lastText = ((JLabel) c).getText();
} else {
lastText = Objects.toString(value, null);
}
setOpaque(c.isOpaque()); // some renderers works with opacity state, we need to consider it
return this;
}

// some UI classes reset background/foreground, so we need to forward them
@Override
public void setBackground(Color bg) {
super.setBackground(bg);
for (Component c : getComponents()) {
c.setBackground(bg);
}
}

@Override
public void setForeground(Color fg) {
super.setForeground(fg);
for (Component c : getComponents()) {
c.setForeground(fg);
}
}

// not sure whether it's required
@Override
public void setFont(Font font) {
super.setFont(font);
for (Component c : getComponents()) {
c.setFont(font);
}
}

@Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);

if (width != 0) {
if (getPreferredSize().width > getSize().width) {
combo.setToolTipText(lastText);
} else {
combo.setToolTipText(null);
}
}
}

}
private static JComboBox<String> createTweakedCombo(boolean enabled) {
JComboBox<String> comboBoxTweaked = new JComboBoxTweaked(items);
comboBoxTweaked.setEnabled(enabled);
return comboBoxTweaked;
}
}

关于java - 如果显示区域太小,带有工具提示的 JComboBox,同时保持外观和感觉,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59157543/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com