Показать ToolTip над компонентом
От: Y-Vladimir США http://yuzhikov.com
Дата: 28.03.06 15:32
Оценка:
Вопрос такой: я выставляю текст подсказки у компонента методом setToolTipText("Some text"), как можно принудительно показать эту подсказку?
Т.е. сделать что-то типа component.showToolTip()?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Показать ToolTip над компонентом
От: Blazkowicz Россия  
Дата: 28.03.06 15:49
Оценка:
Здравствуйте, Y-Vladimir, Вы писали:

YV>Вопрос такой: я выставляю текст подсказки у компонента методом setToolTipText("Some text"), как можно принудительно показать эту подсказку?

YV>Т.е. сделать что-то типа component.showToolTip()?

Блин, реально не нашел нормального способа. Если найдешь — пиши.

Только такой хак:
Action action = jComponent.getActionMap().get("postTip");
action.actionPerformed(new ActionEvent(jComponent, 0, "SHOW"));

Значения 0 и "SHOW" по идее игнорируются и могут быть любыми.
Re: Показать ToolTip над компонентом
От: alexdolgin  
Дата: 28.03.06 15:51
Оценка: +1
Здравствуйте, Y-Vladimir, Вы писали:

YV>Вопрос такой: я выставляю текст подсказки у компонента методом setToolTipText("Some text"), как можно принудительно показать эту подсказку?

YV>Т.е. сделать что-то типа component.showToolTip()?

    public static void activateToolTip(Component source)
    {
        ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
        toolTipManager.mouseEntered(new MouseEvent(source,0,0,0,0,0,0,false));
    }
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Показать ToolTip над компонентом
От: Blazkowicz Россия  
Дата: 28.03.06 16:38
Оценка:
Здравствуйте, Y-Vladimir, Вы писали:

YV>Вопрос такой: я выставляю текст подсказки у компонента методом setToolTipText("Some text"), как можно принудительно показать эту подсказку?

YV>Т.е. сделать что-то типа component.showToolTip()?

Таки баг:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4246122
Re: Показать ToolTip над компонентом
От: Y-Vladimir США http://yuzhikov.com
Дата: 29.03.06 07:48
Оценка:
Спасибо всем за ответы!
У меня такая задача — сделать так, чтобы у компонента JComboBox появлялись подсказки при навигации по элементам (когда он открыт). Вышеприведенные фрагменты работают не совсем так, как надо — подсказки появляются только если курсор мыши находится над комбобоксом. В чем проблема?

Код такой:
public class ComboBoxFrame extends JFrame {
  private JComboBox comboBox = new JComboBox(new String[]{"item 1", "item 2", "item 3"});

  public ComboBoxFrame() {
    comboBox.setToolTipText("Не выбран элемент");
        
    comboBox.getModel().addListDataListener(new ListDataListener() {
      public void intervalAdded(ListDataEvent e) {}        

      public void intervalRemoved(ListDataEvent e) {}

      public void contentsChanged(ListDataEvent e) {                          
                comboBox.setToolTipText(comboBox.getModel().getSelectedItem().toString());

        ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
        toolTipManager.mouseEntered(new MouseEvent(comboBox, 0, 0, 0, 0, 0, 0, false));

        // Action action = comboBox.getActionMap().get("postTip");
        // action.actionPerformed(new ActionEvent(comboBox, 0, "SHOW"));
      }
    });

    add(comboBox, BorderLayout.NORTH);
    setSize(200, 300);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
  }
}

public class Start {
  public static void main(String[] args) {
    (new ComboBoxFrame()).setVisible(true);
    }
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Показать ToolTip над компонентом
От: Blazkowicz Россия  
Дата: 29.03.06 08:30
Оценка:
Здравствуйте, Y-Vladimir, Вы писали:

YV>Спасибо всем за ответы!

YV>У меня такая задача — сделать так, чтобы у компонента JComboBox появлялись подсказки при навигации по элементам (когда он открыт). Вышеприведенные фрагменты работают не совсем так, как надо — подсказки появляются только если курсор мыши находится над комбобоксом. В чем проблема?

[грязное ругательство]... Ну, как обычно издаля зашли
Автор: Y-Vladimir
Дата: 28.03.06
да?

        JComboBox box = new JComboBox(new Object[]{"Item1", "Item2", "Item3", "Item4"});
        box.setRenderer(new ListCellRenderer()
        {
            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
            {
                String text = String.valueOf(value);
                JLabel jLabel = new JLabel(text);
                jLabel.setToolTipText(text);
                return jLabel;
            }
        });


JDK 1.5.0_04 — все работает и так.
Re[3]: Показать ToolTip над компонентом
От: Y-Vladimir США http://yuzhikov.com
Дата: 29.03.06 09:19
Оценка:
B>Ну, как обычно издаля зашли да?
Не совсем, возможно я неточно описал проблему.
Нужно, чтобы в определенном месте относительно комбобокса (например, справа) вылезала подсказка (типа описания) при навигации по элементам клавишами "вверх", "вниз", когда этот комбобокс открыт. Мышь может быть в любом месте экрана. Т.е. фактически вся загвоздка в том, чтобы принудительно показать подсказку на компоненте, когда мы переходим клавишами к следующему элементу.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Показать ToolTip над компонентом
От: Blazkowicz Россия  
Дата: 29.03.06 09:36
Оценка:
Здравствуйте, Y-Vladimir, Вы писали:

YV>Нужно, чтобы в определенном месте относительно комбобокса (например, справа) вылезала подсказка (типа описания) при навигации по элементам клавишами "вверх", "вниз", когда этот комбобокс открыт. Мышь может быть в любом месте экрана. Т.е. фактически вся загвоздка в том, чтобы принудительно показать подсказку на компоненте, когда мы переходим клавишами к следующему элементу.


Аааа... ну тогда ты не тот Listener повесил. Твоё событие порсиходит только когда данные меняются в модели. А тебе нужен ItemListener чтобы узнать когда будет выбран новый элемент.
Re[5]: Показать ToolTip над компонентом
От: OneZerOne Россия  
Дата: 29.03.06 09:53
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Аааа... ну тогда ты не тот Listener повесил. Твоё событие порсиходит только когда данные меняются в модели. А тебе нужен ItemListener чтобы узнать когда будет выбран новый элемент.


Немножко не в тему. Какой Listener по сути не важно, нам необходимо именно ПОКАЗАТЬ подсказку по наступлению какого-либо события, так как с изменением цвета, текста, местоположения проблем не возникает. Т.е. нам необходимо нечто типа метода showTooltip(), а уж откуда его вызывать не принципиально.

Насчет:
B>Таки баг:
B>http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4246122
При попытке изменить toolTipText:
java.lang.IllegalAccessError: tried to access field javax.swing.ToolTipManager.toolTipText from class javax.swing.CustomToolTipManager
... << С уважением, OneZerOne. RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Показать ToolTip над компонентом
От: Blazkowicz Россия  
Дата: 29.03.06 10:29
Оценка:
Здравствуйте, OneZerOne, Вы писали:

B>>Аааа... ну тогда ты не тот Listener повесил. Твоё событие порсиходит только когда данные меняются в модели. А тебе нужен ItemListener чтобы узнать когда будет выбран новый элемент.


OZO>Немножко не в тему. Какой Listener по сути не важно, нам необходимо именно ПОКАЗАТЬ подсказку по наступлению какого-либо события, так как с изменением цвета, текста, местоположения проблем не возникает. Т.е. нам необходимо нечто типа метода showTooltip(), а уж откуда его вызывать не принципиально.


Вообще-то есть чудная комбинация Ctrl+F1.

OZO>Насчет:

B>>Таки баг:
B>>http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4246122
OZO>При попытке изменить toolTipText:
OZO>
OZO>java.lang.IllegalAccessError: tried to access field javax.swing.ToolTipManager.toolTipText from class javax.swing.CustomToolTipManager
OZO>


Да, там workaround идиотский им лучше не пользоваться. Я это к тому что багов с тултипами много, но чинить их никто не собирается.
Re[2]: Показать ToolTip над компонентом
От: Blazkowicz Россия  
Дата: 29.03.06 10:46
Оценка:
Здравствуйте, Y-Vladimir, Вы писали:

YV>У меня такая задача — сделать так, чтобы у компонента JComboBox появлялись подсказки при навигации по элементам (когда он открыт). Вышеприведенные фрагменты работают не совсем так, как надо — подсказки появляются только если курсор мыши находится над комбобоксом. В чем проблема?


Действительно лажа какая-то с комбобоксом. С кнопками, например нормально работает. Даже хаки с созданием не пустой InputMap и editor-а не помогают.
Re[3]: Показать ToolTip над компонентом
От: Blazkowicz Россия  
Дата: 29.03.06 11:05
Оценка: 3 (1) +1
Здравствуйте, Blazkowicz, Вы писали:

B>Действительно лажа какая-то с комбобоксом. С кнопками, например нормально работает. Даже хаки с созданием не пустой InputMap и editor-а не помогают.


Гоню. Все нормально работает через Action после небольшого хака с InputMap

        InputMap inputMap = cbox.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        cbox.setInputMap(JComponent.WHEN_FOCUSED ,inputMap);



        cbox.addItemListener(new ItemListener()
        {
            public void itemStateChanged(ItemEvent e)
            {
                if (cbox.isVisible() && cbox.getSelectedItem() == e.getItem())
                {
                    ActionMap actionMap = cbox.getActionMap();
                    Action action = actionMap.get("postTip");
                    ActionEvent ae = new ActionEvent(cbox, e.getID(), "SHOW");
                    action.actionPerformed(ae);
                }
            }
        });
Re[4]: Показать ToolTip над компонентом
От: OneZerOne Россия  
Дата: 29.03.06 11:22
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Все нормально работает через Action после небольшого хака с InputMap


В actionMap вообще ни одного ключа
public class TestToolTip extends JFrame {
    private JComboBox comboBox = new JComboBox(new String[]{"item 1", "item 2", "item 3"});

    public TestToolTip() {
        comboBox.setToolTipText("Не выбран элемент");

        InputMap inputMap = comboBox.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        comboBox.setInputMap(JComponent.WHEN_FOCUSED, inputMap);

        comboBox.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                if (comboBox.isVisible() && comboBox.getSelectedItem() == e.getItem()) {
                    ActionMap actionMap = comboBox.getActionMap();
                    System.out.println(actionMap);
                    System.out.println(actionMap.keys());            // Здесь возвращает null 
                    for (Object key : actionMap.keys()) {                         // Соотвественно NullPointerException
                        System.out.println("key: " + key);
                    }
                    Action action = actionMap.get("postTip");
                    ActionEvent ae = new ActionEvent(comboBox, e.getID(), "SHOW");
                    action.actionPerformed(ae);
                }
            }
        });

        add(comboBox, BorderLayout.NORTH);
        setSize(200, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        (new TestToolTip()).setVisible(true);
    }
}


Кинь плиз полный исходник
... << С уважением, OneZerOne. RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Показать ToolTip над компонентом
От: Blazkowicz Россия  
Дата: 29.03.06 11:26
Оценка:
Здравствуйте, OneZerOne, Вы писали:

OZO>В actionMap вообще ни одного ключа


Ага.

А так:

public class TestToolTip extends JFrame {
    private JComboBox comboBox = new JComboBox(new String[]{"item 1", "item 2", "item 3"});

    public TestToolTip() {
        //Этот хак нужен для нормальной регистрации компоненты в ToolTipManager
        InputMap inputMap = comboBox.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        comboBox.setInputMap(JComponent.WHEN_FOCUSED, inputMap);
        //А вот здесь эта самая регистрация и происходит
        comboBox.setToolTipText("Не выбран элемент");
//... skipped ...
Re[6]: Показать ToolTip над компонентом
От: OneZerOne Россия  
Дата: 29.03.06 11:48
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, OneZerOne, Вы писали:


OZO>>В actionMap вообще ни одного ключа


B> Ага.

B>А так: ...



Точно , только еще скрывать нужно, чтоб не через раз отображались
    Action hideAction = comboBox.getActionMap().get("hideTip");
    Action showAction = comboBox.getActionMap().get("postTip");
    hideAction.actionPerformed(new ActionEvent(comboBox, 0, "HIDE:)"));
    showAction.actionPerformed(new ActionEvent(comboBox, 0, "SHOW"));


Blazkowicz, Респект!!! Огромное спасибо.
... << С уважением, OneZerOne. RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Показать ToolTip над компонентом
От: Y-Vladimir США http://yuzhikov.com
Дата: 29.03.06 11:58
Оценка:
Blazkowicz, и от меня тоже спасибо!
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Показать ToolTip над компонентом
От: Oval  
Дата: 29.03.06 14:20
Оценка:
Здравствуйте, Y-Vladimir, Вы писали:

YV>Blazkowicz, и от меня тоже спасибо!


А вот чтобы вывести ToolTip в определенной позиции можно?
Или я уже задавал этот вопрос?
Re[9]: Показать ToolTip над компонентом
От: Blazkowicz Россия  
Дата: 29.03.06 14:23
Оценка:
Здравствуйте, Oval, Вы писали:

O>А вот чтобы вывести ToolTip в определенной позиции можно?

O>Или я уже задавал этот вопрос?

Вроде стандартная фича:
http://javaalmanac.com/egs/javax.swing/tooltip_ToolTipLoc.html
Re[9]: Показать ToolTip над компонентом
От: Blazkowicz Россия  
Дата: 29.03.06 14:24
Оценка:
Здравствуйте, Oval, Вы писали:

O>А вот чтобы вывести ToolTip в определенной позиции можно?


http://www.google.com/search?q=swing+tooltip+location
Re[10]: Показать ToolTip над компонентом
От: Oval  
Дата: 29.03.06 14:25
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, Oval, Вы писали:


O>>А вот чтобы вывести ToolTip в определенной позиции можно?

O>>Или я уже задавал этот вопрос?

B>Вроде стандартная фича:

B>http://javaalmanac.com/egs/javax.swing/tooltip_ToolTipLoc.html

Я любдю Swing! Побежал
Re: Показать ToolTip над компонентом
От: Y-Vladimir США http://yuzhikov.com
Дата: 30.03.06 10:23
Оценка:
Опять продолжаю тему ToolTip'ов. Теперь такая проблема возникла. Я создаю свой компонент, наследованный от JComboBox, там перекрываю метод createToolTip() с целью получить кастомизируемую подсказку (цвет, шрифт и т.д.). Все работает, но если я у компонента выставляю свойство setEditable(true), то метод createToolTip() не вызывается и, соответсвенно, подсказка остается дефолтной. Аналогично и с перекрытием метода getLocation().

Код следующий:

public class MyComboBox extends JComboBox {
    private JToolTip toolTip;

    public MyComboBox() {
        toolTip = new JToolTip();
        toolTip.setBackground(Color.RED);
        toolTip.setComponent(this);
        ToolTipManager.sharedInstance().registerComponent(this);

        addItem("Item 1");
        addItem("Item 2");
                
        // Если раскомментировать это свойство, то
        // в консоль строка createToolTip() не выводится
                
        // setEditable(true);
    }

    public JToolTip createToolTip() {
        System.out.println("createToolTip()");
        return toolTip;
    }

    public String getToolTipText() {
        return "Test text";
    }
}

//////////////////////////////////////

public class TestForm extends JFrame {
    private MyComboBox myComboBox;

    public TestForm() {
        myComboBox = new MyComboBox();
        setLayout(new BorderLayout());
        add(myComboBox, BorderLayout.NORTH);

        setSize(300,300);        
    }
}

//////////////////////////////////////

public class Main {
    public static void main(String[] args) {
       TestForm form = new TestForm();

       form.setLocationRelativeTo(null);
       form.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       form.setVisible(true);
    }
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Показать ToolTip над компонентом
От: Blazkowicz Россия  
Дата: 30.03.06 12:35
Оценка:
Здравствуйте, Y-Vladimir, Вы писали:

YV>Опять продолжаю тему ToolTip'ов. Теперь такая проблема возникла. Я создаю свой компонент, наследованный от JComboBox, там перекрываю метод createToolTip() с целью получить кастомизируемую подсказку (цвет, шрифт и т.д.). Все работает, но если я у компонента выставляю свойство setEditable(true), то метод createToolTip() не вызывается и, соответсвенно, подсказка остается дефолтной. Аналогично и с перекрытием метода getLocation().


Не очень понял что там у вас с getLocation(), а вот с setEditable(true) все ясно. Дело в том что JComboBox это составная компанента с точки зрения UI. Например, попробуйте с переопределенным createToolTip(), когда он таки вызывается навести мышь на кнопку комбобокса. Когда комбобокс становится редактируемым добавляется ещё одна компанента: текстовое поле. Можно переопределить Editor. Тогда это будет ваше собственное поле. В противном случае это поле создаётся в UI. То есть больше всего это смахивает на баг L&F, который делигирует текст тултипа но не делегирует дизайн.
Re[6]: Показать ToolTip над компонентом
От: Oval  
Дата: 30.03.06 16:33
Оценка:
Здравствуйте, OneZerOne, Вы писали:

OZO>Насчет:

B>>Таки баг:
B>>http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4246122
OZO>При попытке изменить toolTipText:
OZO>
OZO>java.lang.IllegalAccessError: tried to access field javax.swing.ToolTipManager.toolTipText from class javax.swing.CustomToolTipManager
OZO>


Вот он гад как работает:
package javax.swing;

import java.awt.*;
import java.lang.reflect.*;

public class CustomToolTipManager {

static    Method    show;
static    Method    hide;
static     Field    toolTipText;
static     Field    preferredLocation;
static     Field    insideComponent;
static     Field    enabled;

    /**
     * Shows the tool tip for component <code>c</code> for an indeterminant
     * amount of time.  Since tool tips are regulated by mouse motion events,
     * movement of the mouse after this call is made <i>may</i> result in the tool
     * tip being hidden before it normally times out.
     * <p>
     * If <code>c</code> is a "tall" component, the tool tip is shown near
     * the top, instead of below and slightly to the right, as it is normally.
     *
     * <pre>
     *
     *    normal component:                    "tall" component:
     *    _________________                    _________________
     *    |               |  | 1.5 * height    |               |  | 32
     *    ----------------- \|/                |               | \|/
     *        ________________                 |   ________________
     *    32->| tooltip text |                 32->| tooltip text |
     *        ---------------                  |   ----------------
     *                                         |               |
     *                                         |               | 
     *                                         -----------------
     *
     * </pre>
     *
     * @param c the component
     */
    public static void showToolTipProgramatically(JComponent c) {

        

//        ttm.mouseEvent = null;
        try
        {
            ToolTipManager ttm = ToolTipManager.sharedInstance();

            toolTipText = ttm.getClass().getDeclaredField("toolTipText");
            toolTipText.setAccessible(true);
            toolTipText.set(ttm, c.getToolTipText());

            preferredLocation = ttm.getClass().getDeclaredField("preferredLocation");
            preferredLocation.setAccessible(true);
            preferredLocation.set(ttm, new Point(c.getWidth()/2, c.getHeight()));

            insideComponent = ttm.getClass().getDeclaredField("insideComponent");
            insideComponent.setAccessible(true);
            insideComponent.set(ttm, c);

            enabled = ttm.getClass().getDeclaredField("enabled");
            enabled.setAccessible(true);
            enabled.set(ttm, new Boolean(true));


            show = ttm.getClass().getDeclaredMethod("showTipWindow", null);
            show.setAccessible(true);
            show.invoke(ttm, null);
        }
        catch(Throwable e)
        {
            e.printStackTrace();
        //    System.exit(0);
        }
    }
    public static void hideToolTipProgramatically(JComponent c) {
    
//        ttm.mouseEvent = null;
        try
        {
            ToolTipManager ttm = ToolTipManager.sharedInstance();

            toolTipText = ttm.getClass().getDeclaredField("toolTipText");
            toolTipText.setAccessible(true);
            toolTipText.set(ttm, c.getToolTipText());

            preferredLocation = ttm.getClass().getDeclaredField("preferredLocation");
            preferredLocation.setAccessible(true);
            preferredLocation.set(ttm, new Point(c.getWidth()/2, c.getHeight()));

            insideComponent = ttm.getClass().getDeclaredField("insideComponent");
            insideComponent.setAccessible(true);
            insideComponent.set(ttm, c);

            enabled = ttm.getClass().getDeclaredField("enabled");
            enabled.setAccessible(true);
            enabled.set(ttm, new Boolean(true));


            hide = ttm.getClass().getDeclaredMethod("hideTipWindow", null);
            hide.setAccessible(true);
            hide.invoke(ttm, null);
        }
        catch(Throwable e)
        {
            e.printStackTrace();
        //    System.exit(0);
        }
        
    }

}


ваще в package javax.swing наверно можно и не гадить но проверять уже лень.

Оверквотинг порезан. Автору предупреждение. Blazkowicz
Re[7]: Показать ToolTip над компонентом
От: Oval  
Дата: 30.03.06 17:15
Оценка:
Здравствуйте, Oval, Вы писали:

O>ваще в package javax.swing наверно можно и не гадить но проверять уже лень.

Можно не гадить

Удалено излишнее цитирование. Blazkowicz
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.