Может ли текстовый виджет показывать переполнение с "..." в середине текста вместо конца? - PullRequest
0 голосов
/ 25 апреля 2009

У меня есть JComboBox, который содержит поле со списком MRU и панель дерева каталогов. Вместе они образуют левую панель моего графического интерфейса пользователя (MRU над панелью дерева), которая представляет собой панель JSplitPane, поэтому размер левой панели можно изменять.

Проблема заключается в том, что текст каталога всегда длиннее необходимой ширины, чтобы увидеть этот каталог на панели дерева, поэтому мне приходится изменять размер левой панели гораздо шире, чем необходимо для дерева, чтобы остановить поле со списком показывает усеченное имя каталога.

Поле со списком не очень полезно, когда конец имени файла обрезан, но из-за того, что левая панель достаточно широка для имени файла, очень часто делает ее слишком широкой для всего окна, особенно если не работает максимально. И это обычно только последняя часть имени файла, которая представляет интерес. Если бы я мог только заставить JComboBox каким-то образом показать «начало ... конец» вместо «начало ...», моя проблема была бы решена.

Снимок экрана http://www.freeimagehosting.net/uploads/da9810ed86.png


ОБНОВЛЕНИЕ : У меня есть решение, которое работает (см. Ответ на вопрос ниже), но оно не идеально. Если кто-то знает, как я могу улучшить его, это будет очень цениться.

Ответы [ 2 ]

1 голос
/ 25 апреля 2009

ммХхх, возможно, предоставляя пользовательский рендерер? ....

Я думаю, что это средство визуализации listcell или что-то в этом роде.

Насколько я понимаю, значение по умолчанию переносится, когда недостаточно свободного места, создав / или изменив визуализированную ячейку, вы можете узнать, какая ширина компонента доступна, и изменить текст, который будет отображаться по вашему желанию.

mmmhh Я не был близок с этим API (рендерингом ячеек) в течение нескольких лет, так что, возможно, я немного запутался.

:)

0 голосов
/ 25 апреля 2009

Работая над идеей Оскара об использовании ListCellRenderer, я придумал кое-что, что почти работает ... Значение компонента отображается правильно, но значения списка требуют ужасного взлома.

Требуется взлом, потому что для элементов списка размер средства визуализации (из getSize ()) отражает ширину текста самого длинного элемента, а не ширину пространства, доступного для визуализации значения. Я попытался использовать сам JComboBox, но его ширина включает в себя маленькую кнопку выпадающего меню, поэтому при наличии полосы прокрутки ее ширина не учитывается. Хак - сохранить ширину рендерера, если она меньше ширины поля со списком, и использовать сохраненную ширину, если ширина рендерера больше ширины поля со списком. Это угловой случай, когда ширина рендерера находится между внутренней JLabel и шириной поля со списком.

Так как пространство рендеринга будет шириной поля со списком, за вычетом ширины полосы прокрутки и вставок, если у кого-то есть предложение, как узнать, что в списке есть полоса прокрутки и как получить полосу прокрутки так что я могу извлечь ширину, я все уши. Может быть, я могу сделать list.getParent () и ожидать, что это будет JScrollPane (либо документ JComboBox, либо JList действительно заявляет, что использует панель прокрутки).

Другие предложения, чтобы сделать это лучше, приветствуются.

Код следует:

recentDirs.setRenderer(new ComboTextRenderer(recentDirs));

...

static private class ComboTextRenderer
extends DefaultListCellRenderer
implements SwingConstants
{
JComponent                          parent;
int                                 renderWidth;

ComboTextRenderer(JComponent par) {
    super();

    parent=par;
    renderWidth=-1;
    }

public void paint(Graphics gc) {
    String                          txt=getText();

    int                             len=txt.length();
    int                             wid=getSize().width;
    Insets                          ins=getInsets();
    FontMetrics                     met=gc.getFontMetrics();

    if(renderWidth==-1 || wid<parent.getSize().width) { renderWidth=wid; }
    else                                              { wid=renderWidth; }
    wid-=(ins.left+ins.right);

    if(met.stringWidth(txt)>wid) {
        String rpl=null;
        for(int xa=0,pfx=Math.min(15,((len/2)-1)),sfx=(pfx+2); pfx>0 && sfx<len; xa++) {
            rpl=(txt.substring(0,pfx)+" ... "+txt.substring(sfx));
            if(met.stringWidth(rpl)<=wid) { break; }
            rpl=null;
            if     ((len-sfx)>15) { sfx++; }
            else if((xa%2)==0   ) { pfx--; }
            else                  { sfx++; }
            }
        if(rpl!=null) { setText(rpl); }
        }

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