TITLE:JComboBoxのアイテム文字列を左側からクリップ

JComboBoxのアイテム文字列を左側からクリップ

Posted by terai at 2007-06-18

概要

JComboBoxのアイテム文字列がコンポーネントより長い場合、これを左側からクリップします。

  • &jnlp;
  • &jar;
  • &zip;

#screenshot

サンプルコード

combo02.setRenderer(new DefaultListCellRenderer() {
  public Component getListCellRendererComponent(JList list, Object value, int index,
                          boolean isSelected, boolean cellHasFocus) {
    super.getListCellRendererComponent(list,value,index,isSelected,cellHasFocus);
    //setHorizontalAlignment(JLabel.RIGHT);
    int availableWidth = combo02.getWidth();
    Insets insets;
    if(index<0) {
      insets = combo02.getInsets();
      int buttonSize = combo02.getHeight() - (insets.top + insets.bottom);
      //int buttonSize = getArrowButton(combo02).getWidth();
      availableWidth -= (insets.left + insets.right + buttonSize);
    }
    JTextField field = (JTextField) combo02.getEditor().getEditorComponent();
    insets = field.getMargin();
    availableWidth -= (insets.left + insets.right);

    if(getBorder()!=null) {
      //insets = getBorder().getBorderInsets(this);
      insets = getInsets();
      availableWidth -= (insets.left + insets.right);
    }
    String cellText = (value!=null)?value.toString():"";
    FontMetrics fm = getFontMetrics(getFont());
    if(fm.stringWidth(cellText) > availableWidth) {
      String dots = "...";
      int textWidth = fm.stringWidth(dots);
      int nChars = cellText.length() - 1;
      //for(; nChars > 0; nChars--) {
      while(nChars > 0) {
        textWidth += fm.charWidth(cellText.charAt(nChars));
        if(textWidth > availableWidth) {
          break;
        }
        nChars--;
      }
      setText(dots+cellText.substring(nChars+1));
    }
    return this;
  }
});

解説

標準のJComboBoxでは、長い文字列は右側をクリップするので、上記のサンプルでは左側を切り取り、"..."で置き換えるようにセルレンダラーを変更しています。

ポップアップリストで描画されている場合は、矢印ボタンの幅は無視しています。

Windows環境の1.5と1.6で色々サイズが微妙に異なるようで、うまく表示されない場合があります。

参考リンク

コメント