Переупорядочение SWT / JFace TreeColumn - проблема с setMoveable () - PullRequest
4 голосов
/ 16 сентября 2011

Я пытаюсь настроить многостолбцовый SWT Tree (через JFace TreeViewer), который позволяет пользователю переупорядочивать его столбцы, перетаскивая заголовки столбцов. Тем не менее, первый столбец должен оставаться неподвижным и неподвижным. Я могу использовать метод setMoveable(true) на каждом TreeColumn, кроме первого, чтобы приблизиться, но это не мешает пользователю перетаскивать другой столбец слева от него. Есть идеи, как решить эту проблему?

Вот упрощенный рабочий фрагмент (без JFace) для иллюстрации проблемы:

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;

public class TreeTableColumnMove {

    public static void main(String[] args) {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setLayout(new RowLayout(SWT.HORIZONTAL));
        Tree tree = new Tree(shell, SWT.BORDER | SWT.CHECK);
        tree.setLayoutData(new RowData(-1, 100));
        tree.setHeaderVisible(true);
        for (int i = 0; i < 5; i++) {
            TreeColumn column = new TreeColumn(tree, SWT.CENTER);
            column.setText("Col " + i);
            column.setWidth(60);
            if (i > 0) column.setMoveable(true);
        }
        TreeItem item = new TreeItem(tree, SWT.NONE);
        item.setText(new String[] { "c0", "c1", "c2", "c3", "c4" });
        shell.pack();
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }
}

Ответы [ 2 ]

3 голосов
/ 19 сентября 2011

Вот мое окончательное решение, основанное на ответе Данмека:

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;

    public class TreeTableColumnMove {

        public static void main(String[] args) {
            Display display = new Display();
            Shell shell = new Shell(display);
            shell.setLayout(new RowLayout(SWT.HORIZONTAL));
            final Tree tree = new Tree(shell, SWT.BORDER | SWT.CHECK);
            tree.setLayoutData(new RowData(-1, 100));
            tree.setHeaderVisible(true);
            Listener moveListener = new Listener() {
                public void handleEvent(Event e) {
                    int[] order = tree.getColumnOrder();
                    for(int i=0, col=0; i<order.length; i++) {
                        int tmp = order[i];
                        order[i] = col;
                        col = tmp;
                        if(col == 0)
                            if(i == 0) return;
                            else break;
                    }
                    tree.setColumnOrder(order);
                }
            };

            for (int i = 0; i < 5; i++) {
                TreeColumn column = new TreeColumn(tree, SWT.CENTER);
                column.setText("Col " + i);
                column.setWidth(60);
                if (i == 0)                 
                    column.addListener(SWT.Move, moveListener);
                else
                    column.setMoveable(true);
            }
            TreeItem item = new TreeItem(tree, SWT.NONE);
            item.setText(new String[] { "c0", "c1", "c2", "c3", "c4" });
            shell.pack();
            shell.open();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch())
                    display.sleep();
            }
            display.dispose();
        }
    }
2 голосов
/ 16 сентября 2011

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

Может быть, что-то в этом роде было бы хорошей отправной точкой? По сути, он прослушивает перемещение первого столбца (не напрямую, а смещение в результате перемещения другого столбца слева от него), а затем перетасовывает порядок, чтобы визуально снова был первым столбцом.

Обратите внимание, что независимо от визуального порядка первый созданный столбец всегда будет нулевым (и т. Д.). Метод tree.getColumnOrder () будет упорядочен визуально, со значениями, являющимися индексами созданного порядка (поэтому, если вы поменяете местами 2-й и 3-й столбцы, метод вернет [0, 2, 1, 3, 4])

for (int i = 0; i < 5; i++) {
    TreeColumn column = new TreeColumn(tree, SWT.CENTER);
    column.setText("Col " + i);
    column.setWidth(60);
    if (i > 0) column.setMoveable(true);

    // NEW CODE HERE
    if (i == 0) {

        column.addControlListener(new ControlAdapter() {

            public void controlMoved(ControlEvent e) {

                List<Integer> newOrder = new ArrayList<Integer>();

                // add the first
                newOrder.add(0);

                // loop around all columns
                for (int col : tree.getColumnOrder()) {

                    // if not the first that was added, add to list
                    if (col != 0) {
                        newOrder.add(col);
                    }
                }

                // convert list to array
                int[] newOrderArray = new int[newOrder.size()];
                for (int j = 0; j < newOrder.size(); j++) {
                    newOrderArray[j] = newOrder.get(j);
                }

                // update tree order
                tree.setColumnOrder(newOrderArray);
            }
        });
    }
}
...