2013-10-10 15 views
1

後,我有一個TreeCellEditor具有可變大小(當你選擇在編輯器中的一個組成部分的值,顯示額外的組件)一個JTree。最初顯示編輯器時,它的大小是正確的。但是,如果顯示其他組件,導致其首選大小更大,則編輯器將不會被放大並且其內容將被剪切。如何調整的TreeCellEditor它顯示

我發現,如果我設置的編輯器,它會調整大小,但我想一個辦法把它自動調整它的首選大小變化時。

下面是一個使用JTextField模仿我的編輯的例子。單擊該按鈕,使文本字段首選尺寸較大,但在我的編輯器,這將在編輯器組件內被觸發,我不想明確設置有大小,因爲它是在比作爲樹單元編輯器等情況下使用。

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 

import javax.swing.AbstractAction; 
import javax.swing.DefaultCellEditor; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JTextField; 
import javax.swing.JTree; 

public class Test extends JFrame { 
    @Override 
    public void setVisible(boolean b) { 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JTree tree = new JTree(); 
     tree.setEditable(true); 
     final JTextField field = new JTextField(); 
     tree.setCellEditor(new DefaultCellEditor(field)); 

     JButton button = new JButton(new AbstractAction("Make CellEditor Wider") { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       Dimension size = field.getPreferredSize(); 
       size.width += 50; 
       field.setPreferredSize(size); 
       field.setSize(size); // This forces the tree to show the correct size 
      } 
     }); 

     setLayout(new BorderLayout()); 
     add(tree, BorderLayout.CENTER); 
     add(button, BorderLayout.SOUTH); 
     setSize(500, 500); 
     super.setVisible(b); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Test().setVisible(true); 
      } 
     }); 
    } 
} 
+0

我最近了解到[this](http://stackoverflow.com/a/19225982/230513)。 – trashgod

+0

謝謝,@trashgod。這適用於行高。我對單元格編輯器寬度感興趣。 –

回答

1

基本上,一棵樹(或者更準確地說:它的UI委託方)可以處理具有不同的尺寸比在同一個節點的渲染器組件,儘管他們認爲大小不會在改變編輯器組件單節點編輯過程的生命週期。一個編輯器的壽命期間在開始編輯

  • 觸發編輯器組件下方的節點位置的更新(如果需要)
  • 對於變化的時候,UI

    • 尺寸/位置的編輯器組件,自定義控制器必須聽取這些更改(和/或任何觸發這些更改)然後執行這兩個任務。下面是一個帶有prefSize的textField,取決於其內容以及一個監聽documentChanges並根據需要進行操作的控制器。

      // both height and width depend on content 
      final JTextField field = new JTextField() { 
      
          @Override 
          public Dimension getPreferredSize() { 
           Dimension dim = super.getPreferredSize(); 
           int length = getText().length(); 
           dim.width += length * 10; 
           dim.height += length * 2; 
           return dim; 
          } 
      
      }; 
      // controller listens to changes to dynamically takes over the ui's job 
      DocumentListener l = new DocumentListener() { 
      
          protected void validateEditor(final JTextField field) { 
           // the selectionModel's rowMapper is-a AbstractLayoutCache 
           // BEWARE: implementation detail! 
           TreeSelectionModel model = tree.getSelectionModel(); 
           // invalidate all cached node sizes/locations 
           ((AbstractLayoutCache) model.getRowMapper()).invalidateSizes(); 
           // just a fancy cover method for revalidate/repaint 
           tree.treeDidChange(); 
           // manually set the component's size 
           field.setSize(field.getPreferredSize()); 
          } 
          @Override 
          public void insertUpdate(DocumentEvent e) { 
           validateEditor(field); 
          } 
      
          @Override 
          public void removeUpdate(DocumentEvent e) { 
           validateEditor(field); 
          } 
      
          @Override 
          public void changedUpdate(DocumentEvent e) { 
          } 
      
      }; 
      field.getDocument().addDocumentListener(l); 
      
    +0

    謝謝@kleopatra。由於樹假定大小不會改變,這聽起來像有沒有辦法觸發尺寸變化,而無需實際改變自己編輯的大小。如果編輯器組件包含在佈局管理器中,那麼重新驗證該容器會導致編輯器組件更改大小,但由於樹不使用佈局管理器,因此不會發生這種情況。 –

    +0

    @RangiKeen正是:-) – kleopatra

    +0

    +1爲更好的答案。 :-) – trashgod

    相關問題