Как объединить поле со списком с деревом в Swing?

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

Как бы я сделал что-то подобное, не создавая ничего с нуля?

10.12.2008 21:49:52
4 ОТВЕТА
РЕШЕНИЕ

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

4
10.12.2008 22:40:48
Звучит как небольшая работа, но я полагаю, что подойдет. Я просто должен поиграть с этим.
Daddy Warbox 10.12.2008 22:48:19

Переопределите метод getListCellRendererComponent и создайте компоненты в порядке уровней. Для каждого уровня дерева переместите нарисованную строку на 3 пробела вправо.

Пример:

1

,

, б

2

, с

Исходную реализацию вы можете посмотреть из

public Component getListCellRendererComponent(
                                       JList list,
                                       Object value,
                                       int index,
                                       boolean isSelected,
                                       boolean cellHasFocus) {
        //Get the selected index. (The index param isn't
        //always valid, so just use the value.)
        int selectedIndex = ((Integer)value).intValue();

    if (isSelected) {
        setBackground(list.getSelectionBackground());
        setForeground(list.getSelectionForeground());
    } else {
        setBackground(list.getBackground());
        setForeground(list.getForeground());
    }

    //Set the icon and text.  If icon was null, say so.
    ImageIcon icon = images[selectedIndex];
    String pet = petStrings[selectedIndex];
    setIcon(icon);
    if (icon != null) {
        setText(pet);
        setFont(list.getFont());
    } else {
        setUhOhText(pet + " (no image available)",
                    list.getFont());
    }

    return this;
}
0
10.12.2008 22:02:40
Но разве это не потеряло бы поведение развал-развал
OscarRyz 10.12.2008 22:06:59
Вы могли бы немного изменить код, который вы нашли в Учебном руководстве по Java на ComboBox, чтобы соответствовать вашему объяснению ...
Matthieu 6.10.2014 08:51:43

Вы можете создать ComboBoxEditor, чей компонент (возвращаемый getEditorComponent) является JTree

Хотя, возможно, вы уже пробовали это.

Я не знаю, как это будет выглядеть. Опубликовать скриншот, если вы делаете это работает. :)

РЕДАКТИРОВАТЬ

Я быстро и грязно пытаюсь. Это ужасно, но это только начало.

альтернативный текст http://img120.imageshack.us/img120/2563/yiakxk2.png

Вот код, за что стоит. :(

Вероятно, вы должны начать думать в альтернативах. А как насчет фальшивого Combo, представляющего собой JButton без рамки, когда нажата скрытая панель, появится отображаемое дерево.

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

public class ComboTree {
    public static void main( String [] args ) { 
        JComboBox c = new JComboBox( new String [] { "Hello", "there"});
        c.setModel( new CustomComboModel() );
        c.setEditor( new TreeComboEditor() );
        c.setRenderer( new TreeComboEditor() );
        JFrame frame = new JFrame();
        frame.add( c , BorderLayout.NORTH ) ;
        frame.pack();
        frame.setVisible( true );

    }
}

class CustomComboModel implements ComboBoxModel {
     public Object  getSelectedItem() { return ":P"; }
     public void    setSelectedItem(Object anItem) {}
     public void    addListDataListener(ListDataListener l) {}
     public Object  getElementAt(int index)  { return "at " + index ; }
     public int getSize()  { return 2; }
     public void    removeListDataListener(ListDataListener l)  {}
}
class TreeComboEditor implements ComboBoxEditor, ListCellRenderer {

     // Editor interface
     public void addActionListener(ActionListener l) {}
     public Component   getEditorComponent() {
         return new JTree() ;
         }
     public Object  getItem() { return "";}
     public void    removeActionListener(ActionListener l) {}
     public void    selectAll() {}
     public void    setItem(Object anObject) {}

     // Render interface
     public Component getListCellRendererComponent(JList list,
                                           Object value,
                                           int index,
                                           boolean isSelected,
                                           boolean cellHasFocus) {
        return new JTree();
    }
}
0
10.12.2008 22:34:27
Да, это именно то, о чем я думал, но я не уверен, как он справится со складыванием / разворачиванием по сравнению с выбором элемента. Я скоро попробую.
Daddy Warbox 10.12.2008 22:09:14
Не делай этого. Выглядит ужасно : S
OscarRyz 10.12.2008 22:24:50
Это абсолютно бесполезный код. Он не делает то, что требуется, и делает это наихудшим образом. (-1)
Rastislav Komara 14.12.2008 11:35:37

Эй, угадай что! Это твой счастливый день.

Я использовал эту структуру в прошлом. Это очень полно. Я не знал, что у них это уже есть.

JIDE Soft

альтернативный текст http://img89.imageshack.us/img89/8324/combotreejj1.png

Это не слишком дорого, но вам понадобится некоторое время, чтобы понять API (это не так сложно, но они создали много нового)

2
10.12.2008 22:38:56
Круто, но я не уверен, что был бы готов заплатить за что-то, что я только собираюсь использовать чуть-чуть. Спасибо за находку, хотя.
Daddy Warbox 10.12.2008 22:49:05
Yeap. Согласен. Тогда будет предложено показать / скрыть панель с помощью jtree. Я почти уверен, что именно так они и сделали.
OscarRyz 10.12.2008 22:54:28