sco1
sco1

Reputation: 12214

Modifying uitable column header alignment?

I'm updating my generic data manipulation GUI and I thought I would make use of a uitable instead of a uicontrol listbox to display the path(s) and filename(s) of the loaded files. I noticed the column headers are centered by default, and I can't seem to figure out how to left align them if the filename is longer than the width of the table. I checked the properties returned by get and poked around with findjobj but didn't find anything obvious. My attempt to use an html string was also unsuccessful.

Am I missing something obvious?

Sample code:

function testcode
res = get(0,'ScreenSize');
figdim = [1280 720]; % Main figure size, pixels
handles.mainfig = figure( ...
    'Units', 'Pixels', ...
    'Position', [(res(3) - figdim(1))/2 (res(4) - figdim(2))/2 figdim(1) figdim(2)], ...
    'Name', 'Meep', ...
    'Resize', 'off', ...
    'DockControls', 'off', ...
    'NumberTitle', 'off', ...
    'Toolbar', 'figure' ...
    );
handles.filetable = uitable( ...
    'Parent', handles.mainfig, ...
    'Units', 'normalized', ...
    'Position', [0.038 0.71 0.235 0.1], ...
    'ColumnName', 'File Loaded', ...
    'Data', {'None'} ...
    );
handles.loadfilebtn = uicontrol( ...
    'Parent', handles.mainfig, ...
    'Style', 'pushbutton', ...
    'Units', 'normalized', ...
    'Position', [0.075 0.85 0.16 0.07], ...
    'String', 'This is a Button, Click', ...
    'Callback', {@abutton} ...
    );
guidata(handles.mainfig, handles);
end
function abutton(hObject,~)
handles = guidata(hObject);

filepath = 'C:\folder\folder\folder\folder\folder\folder\folder\folder\folder\superduperreallylongfilename.fileextension';
set(handles.filetable,'Data',{filepath});
set(handles.filetable,'ColumnWidth',{length(filepath)*5});

test = '<html><left />File Loaded</html>';
set(handles.filetable,'ColumnName',test); % Attempt #1, doesn't work
end

Upvotes: 1

Views: 2291

Answers (2)

Dev-iL
Dev-iL

Reputation: 24169

You've mentioned findjobj, which allows you to get the JTable object behind your table. What you're actually trying to do is change some properties of the header, or JTableHeader object. Once you know what you're looking for the solution is easy to find (e.g. this previous thread).

In summary, put this code at the end of the button callback:

function abutton(hObject,~)
%// ....

hTable = handles.filetable;
jScrollpane = findjobj(hTable);
jTable = jScrollpane.getComponent(0).getComponent(0);
%// You can see the list of components using findjobj(hTable).list
%// Part1:
dtcr = javaObject('javax.swing.table.DefaultTableCellRenderer');
dtcr.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
jTable.getColumn(jTable.getColumnName(0)).setHeaderRenderer(dtcr);
%// Part2:
jRenderer = jTable.getTableHeader().getDefaultRenderer();
jRenderer.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
%// Finalization:
jTable.invalidate();

end

Clicking the button then results in:

...the desired result

Several notes:

  1. Here's the documentation of SwingConstants.
  2. The two Parts are supposed to be two different solutions, but I noticed that it only works if both are present (I have no explanation for this).
  3. I tried setting this in the figure creation function, but that didn't work (I have no explanation for this either).
  4. Tested on MATLAB 2014a.

Upvotes: 2

Robert Seifert
Robert Seifert

Reputation: 25232

The easiest workaround I could think of, is to split table and table-header in two separate uitables. It's a little fiddly to set the position vectors properly, but generally it works like a charm. Important: place the "header-uitable" below (in code first) the "data-table". You save some trouble this way.

function testcode
close all
res = get(0,'ScreenSize');
figdim = [1280 720]; % Main figure size, pixels
handles.mainfig = figure( ...
    'Units', 'Pixels', ...
    'Position', [(res(3) - figdim(1))/2 (res(4) - figdim(2))/2 figdim(1) figdim(2)], ...
    'Name', 'Meep', ...
    'Resize', 'off', ...
    'DockControls', 'off', ...
    'NumberTitle', 'off', ...
    'Toolbar', 'figure' ...
    );
handles.tableheader = uitable( ...
    'Parent', handles.mainfig, ...
    'Units', 'normalized', ...
    'Position', [0.038 0.71 0.235 0.1], ...
    'ColumnName', 'File Loaded', ...
    'ColumnWidth', {271} ...
    );
handles.filetable = uitable( ...
    'Parent', handles.mainfig, ...
    'Units', 'normalized', ...
    'Position', [0.038 0.682 0.235 0.1], ...
    'ColumnName', {}, ...
    'Data', {'None'} ...
    );
handles.loadfilebtn = uicontrol( ...
    'Parent', handles.mainfig, ...
    'Style', 'pushbutton', ...
    'Units', 'normalized', ...
    'Position', [0.075 0.85 0.16 0.07], ...
    'String', 'This is a Button, Click', ...
    'Callback', {@abutton} ...
    );
guidata(handles.mainfig, handles);
end
function abutton(hObject,~)
handles = guidata(hObject);

filepath = 'C:\folder\folder\folder\folder\folder\folder\folder\folder\folder\superduperreallylongfilename.fileextension';
set(handles.filetable,'Data',{filepath});
set(handles.filetable,'ColumnWidth',{length(filepath)*5});

end

enter image description here

Upvotes: 2

Related Questions