2

我有一个字符串单元数组(实际上是用户选择的文件列表)。然后我想调出一个用户界面控件,允许用户手动重新排序该列表。

本质上,我希望用户能够选择处理给定文件的顺序。是否已经有一段代码可以执行此操作,或者是否有人对如何执行此操作有任何好的建议?

理想情况下,它将显示字符串列表(文件名),您可以单击一个并单击向上或向下箭头以在列表中向上或向下移动它,或者获得奖励积分:P 它允许拖动它们以重新排序(虽然我怀疑 matlab GUI 是否存在这样的事情)。

4

1 回答 1

2

Matlab 中没有对此的本机支持。最简单的解决方案是使用uitable带有“一些技巧”的 a 。

下面显示的解决方案适用于选择表格中的单个单元格或多个单元格。边界保持不变,即值不会“环绕”。

function reorderableTable

    h(1) = figure(1); clf

    filenames = {...
        'file1.txt.'
        'file2.txt.'
        'file3.txt.'
        'file4.txt.'
        'file5.txt.'
        };

    h(2) = uitable(h(1),...
        'data'    , filenames, ...
        'units'   , 'normalized',...
        'position', [0.1 0.1 0.5 0.85],...
        'CellSelectionCallback', @selectCells);

    h(3) = uicontrol(...
        'style'   , 'pushbutton', ...
        'units'   , 'normalized',...
        'position', [0.7 0.58 0.2 0.15],...
        'string'  , 'Up',...
        'callback', @reOrder);
    h(4) = uicontrol(...
        'style'   , 'pushbutton', ...
        'units'   , 'normalized',...
        'position', [0.7 0.38 0.2 0.15],...
        'string'  , 'Down',...
        'callback', @reOrder);

    set(h(3:4), 'enable', 'off');

    function selectCells(src, evt)
        set(src, 'UserData', evt.Indices);
        if ~isempty(evt.Indices)
            set(h(3:4), 'enable', 'on');
        else
            set(h(3:4), 'enable', 'off');
        end
    end

    function reOrder(src,~)

        up = strcmpi(get(src, 'string'), 'up');

        table = h(2);
        data = get(table, 'Data');
        selected = get(table, 'UserData');        
        selected = selected(:,1);

        if up

            sel  = selected-1;
            not_selected = setdiff(sel, selected);            
            nsel = setdiff(selected, sel);

            if sel(1)>=1 && nsel(end)<=size(data,1)
                new_data = data;
                new_data(sel ,:) = data(selected,:);
                new_data(nsel,:) = data(not_selected,:);            
            else
                return
            end   

        else
            sel  = selected+1;
            not_selected = setdiff(sel, selected);            
            nsel = setdiff(selected, sel);          

            if sel(1)<=size(data,1) && nsel(end)>=1
                new_data = data;
                new_data(sel ,:) = data(selected,:);
                new_data(nsel,:) = data(not_selected,:);                
            else
                return
            end

        end

        set(table, 'Data', new_data);
    end
end

灵感(部分)来自这里

如果你不喜欢嵌套函数,很容易将它们重新定义为子函数,但是你必须传递句柄(这就是我首先选择使用嵌套函数的原因)。

拖放:它可以在本地完成,但只能在uitable列上(请参阅此链接)。我认为这看起来很可怕,但如果你只有一两个文件,它可能会起作用。

否则:您可以使用如上所示的按钮,或搜索一下是否有其他 Java 对象(除了jTable允许您拖动行。我对 Java 不是很熟悉,所以你得去别处看看。

于 2012-10-23T07:01:17.173 回答