2014-02-21 4 views
2

Все еще новичок в Java здесь, пытаясь наполнить слишком продвинутым для моего же блага. Тем не менее, вот что мне нужно сделать: флажок в JXTreeTable. Мой главный класс:Флажок в JXTreeTable

package info.chrismcgee.sky.production; 

import info.chrismcgee.sky.production.treetable.NoRootTreeTableModel; 

import java.awt.Checkbox; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.util.ArrayList; 
import java.util.List; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.ScrollPaneConstants; 
import javax.swing.border.EmptyBorder; 
import javax.swing.border.EtchedBorder; 

import net.miginfocom.swing.MigLayout; 

import org.jdesktop.swingx.JXTreeTable; 

public class TestFrame extends JFrame { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = -1899673458785493250L; 
    private JXTreeTable treeTable; 

    /** 
    * Launch the application. 
    */ 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        TestFrame frame = new TestFrame(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the frame. 
    */ 
    public TestFrame() { 
     setMinimumSize(new Dimension(600, 600)); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setBounds(100, 100, 546, 600); 
     JPanel contentPane = new JPanel(); 
     contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     setContentPane(contentPane); 
     contentPane.setLayout(new MigLayout("", "[grow][grow][grow][100px:n,grow][grow][grow][grow]", "[][251.00,grow][]")); 

     List<Job> jobList = new ArrayList<Job>(); 

     List<ItemDetail> itemList = new ArrayList<ItemDetail>(); 
     itemList.add(new ItemDetail("N10", "N10", 2, 1000, PrintType.PAD, true)); 
     itemList.add(new ItemDetail("N13", "N13", 2, 2000, PrintType.PAD, true)); 

     // create and add the first job with its list of ItemDetail objects 
     jobList.add(new Job(new Checkbox("Print Solutions"), "123456", ShipDate.getDate("02/28/14"), itemList)); 

     List<ItemDetail> itemList2 = new ArrayList<ItemDetail>(); 
     itemList2.add(new ItemDetail("P12", "Green", 1, 250, PrintType.SCREEN, true)); 
     itemList2.add(new ItemDetail("P12", "Purple", 1, 250, PrintType.SCREEN, true)); 
     itemList2.add(new ItemDetail("P12", "Gray", 1, 250, PrintType.SCREEN, true)); 

     // create and add a second job with its list of ItemDetail objects 
     jobList.add(new Job(new Checkbox("Innovators Inc"), "246801", ShipDate.getDate("03/10/14"), itemList2)); 

     // we use a no root model 
     NoRootTreeTableModel noRootTreeTableModel = new NoRootTreeTableModel(jobList); 
     treeTable = new JXTreeTable(noRootTreeTableModel); 
     treeTable.setEditable(false); 
     treeTable.setRootVisible(false); 
     treeTable.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null)); 
     treeTable.getTableHeader().setReorderingAllowed(false); 
     treeTable.getColumn(0).setPreferredWidth(200); 
     treeTable.getColumn(1).setPreferredWidth(75); 
     treeTable.getColumn(2).setPreferredWidth(15); 
      treeTable.getColumn(2).setMinWidth(15); 
      treeTable.getColumn(2).setMaxWidth(15); 
     treeTable.getColumn(3).setPreferredWidth(50); 
      treeTable.getColumn(3).setMaxWidth(50); 
     treeTable.getColumn(4).setPreferredWidth(25); 
     JScrollPane scrollPane = new JScrollPane(treeTable); 
     scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); 
     contentPane.add(scrollPane, "cell 0 1 7 1,grow"); 

    }  
} 

Класс работы (филиалы в TreeTable):

package info.chrismcgee.sky.production; 

import java.awt.Checkbox; 
import java.util.List; 

import org.joda.time.LocalDate; 

public class Job { 

    private Checkbox cbJob; 
    private String idNumber; 
    private LocalDate shipDate; 
    private List<ItemDetail> itemList; 

    public Job(Checkbox cbJob, String idNumber, LocalDate shipDate, List<ItemDetail> itemList) 
    { 
     this.cbJob = cbJob; 
     this.idNumber = idNumber; 
     this.shipDate = shipDate; 
     this.itemList = itemList; 
    } 

    public List<ItemDetail> getItemList() 
    { 
     return itemList; 
    } 

    public void setItemList(List<ItemDetail> itemList) 
    { 
     this.itemList = itemList; 
    } 

    /** 
    * @return the cbJob 
    */ 
    public Checkbox getCbJob() { 
     return cbJob; 
    } 

    /** 
    * @param cbJob the cbJob to set 
    */ 
    public void setCbJob(Checkbox cbJob) { 
     this.cbJob = cbJob; 
    } 

    /** 
    * @return the idNumber 
    */ 
    public String getIdNumber() { 
     return idNumber; 
    } 

    /** 
    * @param idNumber the idNumber to set 
    */ 
    public void setIdNumber(String idNumber) { 
     this.idNumber = idNumber; 
    } 

    /** 
    * @return the shipDate 
    */ 
    public LocalDate getShipDate() { 
     return shipDate; 
    } 

    /** 
    * @param shipDate the shipDate to set 
    */ 
    public void setShipDate(LocalDate shipDate) { 
     this.shipDate = shipDate; 
    } 

} 

Класс OrderDetail (Листья в TreeTable):

package info.chrismcgee.sky.production; 


public class ItemDetail { 

    private String productId; 
    private String detail; 
    private long numColors; 
    private long numQuantity; 
    private PrintType printType; 
    private boolean active; 

    public ItemDetail(String productId, String detail, long numColors, long numQuantity, PrintType printType, boolean active) 
    { 
     this.productId = productId; 
     this.detail = detail; 
     this.numColors = numColors; 
     this.numQuantity = numQuantity; 
     this.printType = printType; 
     this.active = active; 
    } 

    /** 
    * @return the productId 
    */ 
    public String getProductId() { 
     return productId; 
    } 

    /** 
    * @param productId the productId to set 
    */ 
    public void setProductId(String productId) { 
     this.productId = productId; 
    } 

    /** 
    * @return the detail 
    */ 
    public String getDetail() { 
     return detail; 
    } 

    /** 
    * @param detail the detail to set 
    */ 
    public void setDetail(String detail) { 
     this.detail = detail; 
    } 

    /** 
    * @return the numColors 
    */ 
    public long getNumColors() { 
     return numColors; 
    } 

    /** 
    * @param numColors the numColors to set 
    */ 
    public void setNumColors(long numColors) { 
     this.numColors = numColors; 
    } 

    /** 
    * @return the numQuantity 
    */ 
    public long getNumQuantity() { 
     return numQuantity; 
    } 

    /** 
    * @param numQuantity the numQuantity to set 
    */ 
    public void setNumQuantity(long numQuantity) { 
     this.numQuantity = numQuantity; 
    } 

    /** 
    * @return the printType 
    */ 
    public PrintType getPrintType() { 
     return printType; 
    } 

    /** 
    * @param printType the printType to set 
    */ 
    public void setPrintType(PrintType printType) { 
     this.printType = printType; 
    } 

    /** 
    * @return the active 
    */ 
    public boolean isActive() { 
     return active; 
    } 

    /** 
    * @param active the active to set 
    */ 
    public void setActive(boolean active) { 
     this.active = active; 
    } 

} 

и, наконец, NoRootTreeTableModel, который расширяет класс AbstractTreeTableModel, так что корень дерева не отображается:

package info.chrismcgee.sky.production.treetable; 

import info.chrismcgee.sky.production.ItemDetail; 
import info.chrismcgee.sky.production.Job; 

import java.util.List; 

import org.jdesktop.swingx.treetable.AbstractTreeTableModel; 

public class NoRootTreeTableModel extends AbstractTreeTableModel { 

    private final static String[] COLUMN_NAMES = {"Name/Product", "Job #/Detail", "T", 
     "Colors", "Quantity", "Total"}; 

    private List<Job> jobList; 

    public NoRootTreeTableModel(List<Job> jobList) 
    { 
     super(new Object()); 
     this.jobList = jobList; 
    } 

    @Override 
    public int getColumnCount() { 
     return COLUMN_NAMES.length; 
    } 

    @Override 
    public String getColumnName(int column) 
    { 
     return COLUMN_NAMES[column]; 
    } 

    @Override 
    public boolean isCellEditable(Object node, int column) 
    { 
     return false; 
    } 

    @Override 
    public boolean isLeaf(Object node) 
    { 
     return node instanceof ItemDetail; 
    } 

    @Override 
    public int getChildCount(Object parent) { 
     if (parent instanceof Job) { 
      Job job = (Job) parent; 
      return job.getItemList().size(); 
     } 
     return jobList.size(); 
    } 

    @Override 
    public Object getChild(Object parent, int index) { 
     if (parent instanceof Job) { 
      Job job = (Job) parent; 
      return job.getItemList().get(index); 
     } 
     return jobList.get(index); 
    } 

    @Override 
    public int getIndexOfChild(Object parent, Object child) { 
     Job job = (Job) parent; 
     ItemDetail item = (ItemDetail) child; 
     return job.getItemList().indexOf(item); 
    } 

    @Override 
    public Object getValueAt(Object node, int column) { 
     if (node instanceof Job) { 
      Job job = (Job) node; 
      switch (column) { 
       case 0: 
        return job.getCbJob(); 
       case 1: 
        return job.getIdNumber(); 
      } 
     } else if (node instanceof ItemDetail) { 
      ItemDetail item = (ItemDetail) node; 
      switch (column) { 
       case 0: 
        return item.getProductId(); 
       case 1: 
        return item.getDetail(); 
       case 2: 
        return item.getPrintType(); 
       case 3: 
        return item.getNumColors(); 
       case 4: 
        return item.getNumQuantity(); 
       case 5: 
        return item.getNumColors() * item.getNumQuantity(); 
      } 
     } 
     return null; 
    } 

} 

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

Когда код запущен, я не устанавливаю флажок для ветвей; вместо этого я получаю то, что представляется строковым представлением кода ячейки: Checkbox in a TreeTable http://imageshack.com/a/img713/250/dl87.jpg

Да? Как это произошло и, что более важно, как я могу установить флажок?

ответ

6

Вы никогда не должны добавлять компоненты к модели, вместо этого вы должны предоставить TreeCellRenderer для визуализации значения узла. Узел, вероятно, использует значение объекта пользователя, присвоенный ему toString ...

Посмотрите на How to Use Trees и Customizing a Tree's Display для получения более подробной информации

Пример Ripped Прямо из Customizing a Tree's Display

Check Boxes

Я оставлю его для создания редактора и определения того, как установить флажок

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Vector; 
import javax.swing.ButtonGroup; 
import javax.swing.JCheckBox; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JRadioButton; 
import javax.swing.JScrollPane; 
import javax.swing.JTree; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.event.TreeModelEvent; 
import javax.swing.event.TreeModelListener; 
import javax.swing.tree.TreeCellRenderer; 
import javax.swing.tree.TreeModel; 
import javax.swing.tree.TreePath; 
import javax.swing.tree.TreeSelectionModel; 

public class TreeExample { 

    public static void main(String[] args) { 
     //Schedule a job for the event-dispatching thread: 
     //creating and showing this application's GUI. 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 

       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 

        //Create and set up the window. 
        JFrame frame = new JFrame("GenealogyExample"); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

        //Create and set up the content pane. 
        GenealogyExample newContentPane = new GenealogyExample(); 
        newContentPane.setOpaque(true); //content panes must be opaque 
        frame.setContentPane(newContentPane); 

        //Display the window. 
        frame.pack(); 
        frame.setLocationRelativeTo(null); 
        frame.setVisible(true); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public static class GenealogyExample extends JPanel 
      implements ActionListener { 

     private JTree tree; 
     private static String SHOW_ANCESTOR_CMD = "showAncestor"; 

     public GenealogyExample() { 
      super(new BorderLayout()); 

      //Construct the panel with the toggle buttons. 
      JRadioButton showDescendant 
        = new JRadioButton("Show descendants", true); 
      final JRadioButton showAncestor 
        = new JRadioButton("Show ancestors"); 
      ButtonGroup bGroup = new ButtonGroup(); 
      bGroup.add(showDescendant); 
      bGroup.add(showAncestor); 
      showDescendant.addActionListener(this); 
      showAncestor.addActionListener(this); 
      showAncestor.setActionCommand(SHOW_ANCESTOR_CMD); 
      JPanel buttonPanel = new JPanel(); 
      buttonPanel.add(showDescendant); 
      buttonPanel.add(showAncestor); 

      //Construct the tree. 
      tree = new JTree(new GenealogyModel(getGenealogyGraph())); 
     tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); 
      tree.setCellRenderer(new CheckBoxTreeCellRenderer()); 

      JScrollPane scrollPane = new JScrollPane(tree); 
      scrollPane.setPreferredSize(new Dimension(200, 200)); 

      //Add everything to this panel. 
      add(buttonPanel, BorderLayout.PAGE_START); 
      add(scrollPane, BorderLayout.CENTER); 
     } 

     /** 
     * Required by the ActionListener interface. Handle events on the 
     * showDescendant and showAncestore buttons. 
     */ 
     public void actionPerformed(ActionEvent ae) { 
      if (ae.getActionCommand() == SHOW_ANCESTOR_CMD) { 
       showAncestor(true); 
      } else { 
       showAncestor(false); 
      } 
     } 

     public void showAncestor(boolean b) { 
     Object newRoot = null; 
     TreePath path = tree.getSelectionModel().getSelectionPath(); 
     if (path != null) { 
      newRoot = path.getLastPathComponent(); 
     } 
     ((GenealogyModel)tree.getModel()).showAncestor(b, newRoot); 
    } 

     /** 
     * Constructs the genealogy graph used by the model. 
     */ 
     public Person getGenealogyGraph() { 
      //the greatgrandparent generation 
      Person a1 = new Person("Jack (great-granddaddy)"); 
      Person a2 = new Person("Jean (great-granny)"); 
      Person a3 = new Person("Albert (great-granddaddy)"); 
      Person a4 = new Person("Rae (great-granny)"); 
      Person a5 = new Person("Paul (great-granddaddy)"); 
      Person a6 = new Person("Josie (great-granny)"); 

      //the grandparent generation 
      Person b1 = new Person("Peter (grandpa)"); 
      Person b2 = new Person("Zoe (grandma)"); 
      Person b3 = new Person("Simon (grandpa)"); 
      Person b4 = new Person("James (grandpa)"); 
      Person b5 = new Person("Bertha (grandma)"); 
      Person b6 = new Person("Veronica (grandma)"); 
      Person b7 = new Person("Anne (grandma)"); 
      Person b8 = new Person("Renee (grandma)"); 
      Person b9 = new Person("Joseph (grandpa)"); 

      //the parent generation 
      Person c1 = new Person("Isabelle (mom)"); 
      Person c2 = new Person("Frank (dad)"); 
      Person c3 = new Person("Louis (dad)"); 
      Person c4 = new Person("Laurence (dad)"); 
      Person c5 = new Person("Valerie (mom)"); 
      Person c6 = new Person("Marie (mom)"); 
      Person c7 = new Person("Helen (mom)"); 
      Person c8 = new Person("Mark (dad)"); 
      Person c9 = new Person("Oliver (dad)"); 

      //the youngest generation 
      Person d1 = new Person("Clement (boy)"); 
      Person d2 = new Person("Colin (boy)"); 

      Person.linkFamily(a1, a2, new Person[]{b1, b2, b3, b4}); 
      Person.linkFamily(a3, a4, new Person[]{b5, b6, b7}); 
      Person.linkFamily(a5, a6, new Person[]{b8, b9}); 
      Person.linkFamily(b3, b6, new Person[]{c1, c2, c3}); 
      Person.linkFamily(b4, b5, new Person[]{c4, c5, c6}); 
      Person.linkFamily(b8, b7, new Person[]{c7, c8, c9}); 
      Person.linkFamily(c4, c7, new Person[]{d1, d2}); 

      return a1; 
     } 

    } 

    public static class CheckBoxTreeCellRenderer implements TreeCellRenderer { 

     private JCheckBox cb = new JCheckBox(); 

     @Override 
     public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { 

      cb.setText(value.toString()); 
      cb.setOpaque(selected); 
      if (selected) { 
       cb.setBackground(UIManager.getColor("Tree.selectionBackground")); 
       cb.setForeground(UIManager.getColor("Tree.selectionForeground")); 
      } else { 
       cb.setBackground(tree.getBackground()); 
       cb.setForeground(tree.getForeground()); 
      } 

      return cb; 

     } 

    } 

    public static class GenealogyModel implements TreeModel { 

     private boolean showAncestors; 
     private Vector<TreeModelListener> treeModelListeners 
       = new Vector<TreeModelListener>(); 
     private Person rootPerson; 

     public GenealogyModel(Person root) { 
      showAncestors = false; 
      rootPerson = root; 
     } 

     /** 
     * Used to toggle between show ancestors/show descendant and to change the 
     * root of the tree. 
     */ 
     public void showAncestor(boolean b, Object newRoot) { 
      showAncestors = b; 
      Person oldRoot = rootPerson; 
      if (newRoot != null) { 
       rootPerson = (Person) newRoot; 
      } 
      fireTreeStructureChanged(oldRoot); 
     } 

//////////////// Fire events ////////////////////////////////////////////// 
     /** 
     * The only event raised by this model is TreeStructureChanged with the root 
     * as path, i.e. the whole tree has changed. 
     */ 
     protected void fireTreeStructureChanged(Person oldRoot) { 
      int len = treeModelListeners.size(); 
      TreeModelEvent e = new TreeModelEvent(this, 
        new Object[]{oldRoot}); 
      for (TreeModelListener tml : treeModelListeners) { 
       tml.treeStructureChanged(e); 
      } 
     } 

//////////////// TreeModel interface implementation /////////////////////// 
     /** 
     * Adds a listener for the TreeModelEvent posted after the tree changes. 
     */ 
     public void addTreeModelListener(TreeModelListener l) { 
      treeModelListeners.addElement(l); 
     } 

     /** 
     * Returns the child of parent at index index in the parent's child array. 
     */ 
     public Object getChild(Object parent, int index) { 
      Person p = (Person) parent; 
      if (showAncestors) { 
       if ((index > 0) && (p.getFather() != null)) { 
        return p.getMother(); 
       } 
       return p.getFather(); 
      } 
      return p.getChildAt(index); 
     } 

     /** 
     * Returns the number of children of parent. 
     */ 
     public int getChildCount(Object parent) { 
      Person p = (Person) parent; 
      if (showAncestors) { 
       int count = 0; 
       if (p.getFather() != null) { 
        count++; 
       } 
       if (p.getMother() != null) { 
        count++; 
       } 
       return count; 
      } 
      return p.getChildCount(); 
     } 

     /** 
     * Returns the index of child in parent. 
     */ 
     public int getIndexOfChild(Object parent, Object child) { 
      Person p = (Person) parent; 
      if (showAncestors) { 
       int count = 0; 
       Person father = p.getFather(); 
       if (father != null) { 
        count++; 
        if (father == child) { 
         return 0; 
        } 
       } 
       if (p.getMother() != child) { 
        return count; 
       } 
       return -1; 
      } 
      return p.getIndexOfChild((Person) child); 
     } 

     /** 
     * Returns the root of the tree. 
     */ 
     public Object getRoot() { 
      return rootPerson; 
     } 

     /** 
     * Returns true if node is a leaf. 
     */ 
     public boolean isLeaf(Object node) { 
      Person p = (Person) node; 
      if (showAncestors) { 
       return ((p.getFather() == null) 
         && (p.getMother() == null)); 
      } 
      return p.getChildCount() == 0; 
     } 

     /** 
     * Removes a listener previously added with addTreeModelListener(). 
     */ 
     public void removeTreeModelListener(TreeModelListener l) { 
      treeModelListeners.removeElement(l); 
     } 

     /** 
     * Messaged when the user has altered the value for the item identified by 
     * path to newValue. Not used by this model. 
     */ 
     public void valueForPathChanged(TreePath path, Object newValue) { 
      System.out.println("*** valueForPathChanged : " 
        + path + " --> " + newValue); 
     } 
    } 

    public static class Person { 

     Person father; 
     Person mother; 
     List<Person> children; 
     private String name; 

     public Person(String name) { 
      this.name = name; 
      mother = father = null; 
      children = new ArrayList<Person>(); 
     } 

     /** 
     * Link together all members of a family. 
     * 
     * @param pa the father 
     * @param ma the mother 
     * @param kids the children 
     */ 
     public static void linkFamily(Person pa, 
       Person ma, 
       Person[] kids) { 
      for (Person kid : kids) { 
       pa.children.add(kid); 
       ma.children.add(kid); 
       kid.father = pa; 
       kid.mother = ma; 
      } 
     } 

/// getter methods /////////////////////////////////// 
     public String toString() { 
      return name; 
     } 

     public String getName() { 
      return name; 
     } 

     public Person getFather() { 
      return father; 
     } 

     public Person getMother() { 
      return mother; 
     } 

     public int getChildCount() { 
      return children.size(); 
     } 

     public Person getChildAt(int i) { 
      return (Person) children.get(i); 
     } 

     public int getIndexOfChild(Person kid) { 
      return children.indexOf(kid); 
     } 
    } 
} 
+0

Хорошо, не могли бы вы рассказать мне, как использовать «TreeCellRenderer», чтобы флажки отображались в стандартном? Мне жаль, что я так невежественна. – Sturm

+0

Чка ссылки, попробуйте примеры – MadProgrammer

+0

Да, я дважды читал эти ссылки.Существует много информации о том, как настроить внешний вид дерева, изменить значок узла и задать текст всплывающей подсказки. Я ничего не вижу о наличии флажка или другого такого элемента в дереве. Я бы подумал, что такая вещь должна быть довольно распространенной. Даже Windows имеет возможность показывать флажки во всех папках и файлах в Проводнике, в том числе в дереве папок. – Sturm

1

С несколькими минутами поиска в Интернете я нашел этот CheckBox node tree sample и этот blog post about JXTreeTable with CheckBoxes, а также этот very simple solution.

Не тот, что вы ищете?

+0

DuncanKinnear, спасибо за ваши ссылки, но это все еще не совсем что я ищу. Самая близкая ваша последняя ссылка, на блог huionn в блоге. Когда я разместил щедрость, я специально попросил некоторую персонализированную, 1-на-1, пошаговую помощь в том, чтобы сделать эту работу в моей конкретной ситуации, так как я лучше всего учусь. Не просто бросив набор ссылок и сказал: «Вы должны были найти их сами». Я понимаю, что прошу многого, и я собираюсь сходить с ума, потому что еще не нашел хорошего человека, который мог бы провести меня через эту проблему. – Sturm

2

Sturm дает большую часть решения.

Недостающий кусок головоломки в том, что вы можете получить JTree от JXTreeTable, как это:

JTree tree = (JTree) treeTable.getCellRenderer(0, treeTable.getHierarchicalColumn()) 

Это немного рубить, но я не знаю, есть ли у них лучше API для поймите.

+0

Спасибо, я просто искал способ получить доступ к 'JTree'. Вероятно, это спасло меня! – qqilihq