2009-04-25 18 views
0

我有一个JComboBox,其中包含一个MRU列表组合框和一个目录树面板。一起,这两个形成我的GUI(在MRU是树面板上方),其是调整JSplitPane的左侧面板,所以左侧面板是可调整大小。文本小部件可以在文本中间而不是结尾处显示“...”溢出吗?

它在该目录文本的一个问题是永远比要求的宽度更长的时间才能看到树面板目录,所以我必须大小我的左侧窗格中远远超过需要的树,以更宽停止组合框显示截断的目录名称。

组合框在截断文件名的末尾并不是非常有用,但是使左窗格足够宽以容纳文件名,这通常会使整个窗口变得过于宽泛,尤其是对于整个窗口而言,如果不是最大化运行。它通常只是文件名的尾部部分。如果我只能导致JComboBox中以某种方式秀“开始......结束”,而不是“启动...”我的问题将得到解决。

Screen Shot http://www.freeimagehosting.net/uploads/da9810ed86.png


更新:我有工作(见下文自答案)的解决方案,但它并不完美。如果有人知道我可以如何改进它,那将非常感激。

回答

0

从使用ListCellRenderer的奥斯卡的想法工作,我已经提出了一些几乎工程...该组件值正确呈现,但列表的值需要一个丑陋的黑客。

因为对于列表项,渲染器的大小(来自getSize())反映的是最长项目的文本宽度,而不是可用于渲染值的空间宽度,所以需要hack。我尝试过使用JComboBox本身,但它的宽度包含了小小的下拉按钮,所以如果有一个滚动条存在,它的宽度将不被考虑。如果渲染器的宽度小于组合框的宽度,则使用存储宽度,如果渲染器的宽度大于组合框的宽度,则使用存储的宽度。渲染器的宽度介于内部JLabel的宽度和组合框的宽度之间时,会出现拐角情况。

由于渲染空间将是组合框的宽度,减少滚动条和插入的宽度,如果任何人有一个建议,我怎么能知道列表有一个滚动条,以及如何获得滚动条让我可以提取宽度,我都是耳朵。也许我可以做list.getParent()并期望它是一个JScrollPane(JComboBox或JList doco确实声明它使用滚动窗格)。

其他建议这样做更好的欢迎。

代码如下:

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

mmhhh也许提供一个自定义渲染器?...。

我认为这是listcell元素里面渲染器或类似的东西。

据我所知,当没有足够的可用空间时,通过创建/或修改渲染的单元格可以知道什么是可用的组件宽度,并修改要在您的意愿下渲染的文本。

mmmhh我还没有接近从API(细胞渲染的东西)了几年,所以我可能是可能有点糊涂了。

:)

+0

我给一个旋转这个周末;假设它的工作原理,你介意我是否用渲染器代码编辑你的答案,然后接受它? – 2009-04-25 00:48:49

相关问题