Пользовательская подсказка Java с компонентами Swing, так как содержимое не отображается - PullRequest
13 голосов
/ 01 марта 2012

Я пытаюсь показать несколько изображений во всплывающей подсказке компонента, нашел createToolTip() и внедрил пользовательский интерфейс, который добавляет необходимые компоненты, например:

setComponent(component);

JPanel images = new JPanel(null);
images.setLayout(new BoxLayout(images, BoxLayout.X_AXIS));
for(ImageIcon icon:myIcons) {
    images.add(new JLabel(icon));
}

JPanel content = new JPanel(new BorderLayout());
content.add(new JLabel(title), BorderLayout.NORTH);
content.add(new JLabel(description));
content.add(images, BorderLayout.SOUTH);

add(content);

Однако все, что я вижу, это маленькая точка, показывая, что подсказка отображается, но размер игнорируется.Что мне не хватает при реализации пользовательской подсказки?

Ответы [ 6 ]

15 голосов
/ 02 марта 2012

Подсказки могут отображать HTML.Если вы можете сформировать URL-адреса к изображениям (непрактично, если они генерируются в памяти, но обычно это можно сделать иначе), легко написать некоторый HTML-код, который будет загружать изображения, и использовать этот HTML-код в качестве подсказки.


EG

MultiIconToolTip

import javax.swing.*;

class MultiIconToolTip {

    public static void main(String[] args) throws Exception {
        final String html =
            "<html><body>" +
            "<img src='" +
            "http://i.stack.imgur.com/OVOg3.jpg" +
            "' width=160 height=120> " +
            "<img src='" +
            "http://i.stack.imgur.com/lxthA.jpg" +
            "' width=160 height=120>" +
            "<p>Look Ma, no hands!";
        SwingUtilities.invokeLater( new Runnable() {
            public void run() {
                JLabel hover = new JLabel("Point at me!");
                hover.setToolTipText(html);
                JOptionPane.showMessageDialog(null, hover);
            }
        });
    }
}
12 голосов
/ 02 марта 2012

Базовые "проблемы" заключаются в том, что JToolTip

  • не является , спроектированным как контейнер, это только случайно контейнер, потому что JComponent является.Для Swing «не-контейнер» ответственность делегата пользовательского интерфейса выполнять роль LayoutManager.
  • недостаточно богат, он может обрабатывать только текст (по крайней мере, с помощью html для аварийной двери, который является любимым для @ Эндрю: -)

Обход этих ограничений в основномведет этот виджет чуть ли не через край.Чистое решение приведет к появлению нового компонента. С другой стороны, ОП уже нашел винты для настройки.Единственное, что можно немного улучшить - это не вызывать setXXSize и не устанавливать пользовательский интерфейс.Вместо этого сделайте так, чтобы он вел себя как контейнер, переопределив getXXSize (), например:

@Override
public Dimension getPreferredSize() {
    if (getLayout() != null) {
        return getLayout().preferredLayoutSize(this);
    }
    return super.getPreferredSize();
}
4 голосов
/ 01 марта 2012

Я бы предложил использовать JWindow или un_decorated JDialog в качестве всплывающего окна (используется по умолчанию для JCalendar или JDatePicker) вместо JTooltip, для более приятного вывода в GUI реализует Светопрозрачные и фасонные окна

3 голосов
/ 02 марта 2012

По сути, отсутствуют две вещи. Прежде всего, JToolTip расширяет JComponent и, в отличие от JPanel, не имеет макета по умолчанию. Чтобы растянуть content по всплывающей подсказке, используйте BorderLayout.

setLayout(new BorderLayout());

Вторая проблема - размер. ToolTipManager соответствует предпочтительному размеру наконечника инструмента. В то время как BorderLayout вычисляет размер, ToolTipUI игнорирует его. Итак, есть две альтернативы: вручную установить предпочтительный размер ...

setPreferredSize(content.getPreferredSize());

Обратите внимание, что это не делает макет устаревшим; в противном случае вы получите пустую подсказку нужного размера.

... или подкласс ToolTipUI для соблюдения макета, что я и сделал. Полученный код:

setComponent(StadtLabel.this);

JPanel images = new JPanel(null);
waren.setLayout(new BoxLayout(waren, BoxLayout.X_AXIS));
for(ImageIcon icon:myIcons) {
    JLabel lbl = new JLabel(icon);
}

JPanel content = new JPanel(new BorderLayout());
content.add(new JLabel(title), BorderLayout.NORTH);
content.add(new JLabel(description));
content.add(images, BorderLayout.SOUTH);

setLayout(new BorderLayout());
add(content);
setUI(new ToolTipUI() {
    @Override
    public Dimension getMinimumSize(JComponent c) {
        return c.getLayout().minimumLayoutSize(c);
    }

    @Override
    public Dimension getPreferredSize(JComponent c) {
        return c.getLayout().preferredLayoutSize(c);
    }

    @Override
    public Dimension getMaximumSize(JComponent c) {
        return getPreferredSize(c);
    }
});
3 голосов
/ 01 марта 2012

Это может звучать глупо, но вы пробовали установить границы для JPanel?

setBounds(100, 100, 150, 50);

И вы можете попробовать установить разрыв между компонентами в BorderLayout

JPanel content = new JPanel(new BorderLayout(1,1));
0 голосов
/ 28 июля 2015

Вместо изобретения колеса попробуйте это: https://github.com/timmolderez/balloontip. Вы можете поместить любой контент как JComponent.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...