In previous projects, I just used the text uicontrol to handle this, but I always found the result aesthetically unappealing when a large amount of data needed to be summarized close to the user-entered data. Figure 1 shows an example of this. While it looks adequate for this particular case, I don't like the way it looks scaled up when there are dozens of user inputs.
Figure 1: Using a text uicontrol to summarize information derived from user-entered data |
I wanted to use the edit uicontrols to hold this information, but by its nature the information in that box can be changed by the user. Disabling the edit box grays out the box and text inside, which, in my opinion, doesn't look particularly good. See figure 2.
Figure 2: Examples of enabled and disabled edit uicontrols |
Once we have the object's Java handle, we can use its setEditable method to make the control uneditable. An example is shown in the code below.
function edit_box clear all; clc; close all; f = figure(); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% Main entry uipanel %%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% entry_panel = uipanel('Parent', f, 'Title', 'Parameters', ... 'Position', [0.05, 0.55, 0.5, 0.4]); number_label = uicontrol('Parent', entry_panel, ... 'Style', 'text', ... 'String', 'Number of spheres', ... 'HorizontalAlignment', 'left', ... 'Position', [10 120, 100, 17]); number_entry = uicontrol('Parent', entry_panel', ... 'Style', 'edit', ... 'Position', [120 120, 75, 20]); radius_label = uicontrol('Parent', entry_panel, ... 'Style', 'text', ... 'String', 'Radii of spheres', ... 'HorizontalAlignment', 'left', ... 'Position', [10 90, 100, 17]); radius_entry = uicontrol('Parent', entry_panel', ... 'Style', 'edit', ... 'Position', [120 90, 75, 20]); radius_unit_label = uicontrol('Parent', entry_panel, ... 'Style', 'text', ... 'String', 'cm', ... 'HorizontalAlignment', 'left', ... 'Position', [200 90, 40, 17]); density_label = uicontrol('Parent', entry_panel, ... 'Style', 'text', ... 'String', 'Density of spheres', ... 'HorizontalAlignment', 'left', ... 'Position', [10 60, 100, 17]); density_entry = uicontrol('Parent', entry_panel', ... 'Style', 'edit', ... 'Position', [120 60, 75, 20]); density_units_jlabel = javaObjectEDT('javax.swing.JLabel', ... '<HTML>g / cm<SUP>3</SUP></HTML>'); [density_units_label, hcontainer] = javacomponent(density_units_jlabel, ... [200 60, 40, 22], entry_panel); % Create a font for the JLabel that matches the default MATLAB font for text % uicontrols label_font = java.awt.Font('MS Sans Serif', java.awt.Font.PLAIN, 11); density_units_label.setFont(label_font); update_button = uicontrol('Parent', entry_panel, ... 'String', 'Update', ... 'Callback', @update_fields, ... 'Position', [10 15 75 30]); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% Main entry uipanel %%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% summary_panel = uipanel('Parent', f, 'Title', 'Summary', ... 'Position', [0.05, 0.05, 0.5, 0.4]); volume_per_sphere_label = uicontrol('Parent', summary_panel, ... 'Style', 'text', ... 'String', 'Volume per sphere', ... 'HorizontalAlignment', 'left', ... 'Position', [10 120, 100, 17]); volume_per_sphere_entry = uicontrol('Parent', summary_panel', ... 'Style', 'edit', ... 'Position', [120 120, 75, 20]); volume_per_sphere_units_jlabel= javaObjectEDT('javax.swing.JLabel', ... '<HTML>cm<SUP>3</SUP></HTML>'); [volume_per_sphere_units_label, hcontainer] = javacomponent( ... volume_per_sphere_units_jlabel, ... [200 120, 40, 22], summary_panel); volume_per_sphere_units_jlabel.setFont(label_font); total_volume_label = uicontrol('Parent', summary_panel, ... 'Style', 'text', ... 'String', 'Total volume', ... 'HorizontalAlignment', 'left', ... 'Position', [10 90, 100, 17]); total_volume_entry = uicontrol('Parent', summary_panel', ... 'Style', 'edit', ... 'Position', [120 90, 75, 20]); total_volume_units_jlabel = javaObjectEDT('javax.swing.JLabel', ... '<HTML>cm<SUP>3</SUP></HTML>'); [total_volume_units_label, hcontainer] = javacomponent( ... total_volume_units_jlabel, ... [200 90, 40, 22], summary_panel); total_volume_units_jlabel.setFont(label_font); total_mass_label = uicontrol('Parent', summary_panel, ... 'Style', 'text', ... 'String', 'Total mass', ... 'HorizontalAlignment', 'left', ... 'Position', [10 60, 100, 17]); total_mass_entry = uicontrol('Parent', summary_panel', ... 'Style', 'edit', ... 'Position', [120 60, 75, 20]); total_mass_unit_label = uicontrol('Parent', summary_panel, ... 'Style', 'text', ... 'String', 'g', ... 'HorizontalAlignment', 'left', ... 'Position', [200 60, 40, 17]); % Make the edit entries in this section uneditable by accessing their Java % handle and setting editable to false. jvolume_per_sphere_entry = findjobj(volume_per_sphere_entry); jvolume_per_sphere_entry.setEditable(false); jtotal_volume_entry = findjobj(total_volume_entry); jtotal_volume_entry.setEditable(false); jtotal_mass_entry = findjobj(total_mass_entry); jtotal_mass_entry.setEditable(false); %%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% Calback function %%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%% function update_fields(source, events) % Read inputs from edit boxes N = str2num( number_entry.String ); r = str2num( radius_entry.String ); rho = str2num( density_entry.String ); % Calculate the needed values V_sphere = 4/3 * pi * r^3; V_total = N * V_sphere; M = rho * V_total; % Update the edit boxes volume_per_sphere_entry.String = num2str( V_sphere ); total_volume_entry.String = num2str( V_total ); total_mass_entry.String = num2str( M ); end end
This code produces the window shown if Fig. 3. The edit uicontrols in the Summary pane are not changeable by the user, though one can highlight the values and copy them to the clipboard if need be.
Figure 3. Example of window where several edit uicontrols are set to be non-editable while not being grayed out. |
label_font = java.awt.Font('MS Sans Serif', java.awt.Font.PLAIN, 11); density_units_label.setFont(label_font);
This is an example of using Java directly in MATLAB which is more a forte of the Undocumented MATLAB site so I won't dwell on it here.