Подтвердить что ты не робот

Пользовательский кончик инструмента Java с компонентами Swing, поскольку контент не отображается

Я пытаюсь показать несколько изображений в подсказке компонента, нашел 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);

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

4b9b3361

Ответ 1

Основными "проблемами" являются JToolTip

  • - не предназначен как контейнер, он только случайно является контейнером, потому что JComponent. Для Swing "not-container" его обязанностью ui-delegate выступать в качестве LayoutManager.
  • недостаточно богат, он может обрабатывать только текстовые сообщения (по крайней мере, с html-дверцей аварийной двери, которая является любимым @Andrew: -)

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

@Override
public Dimension getPreferredSize() {
    if (getLayout() != null) {
        return getLayout().preferredLayoutSize(this);
    }
    return super.getPreferredSize();
}

Ответ 2

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


например.

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);
            }
        });
    }
}

Ответ 3

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

Ответ 4

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

setBounds(100, 100, 150, 50);

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

JPanel content = new JPanel(new BorderLayout(1,1));

Ответ 5

По существу, две вещи отсутствуют. Прежде всего, JToolTip extends 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);
    }
});

Ответ 6

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