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...
Пока на собственное сообщение не было ответов, его можно удалить.