Customize how my class is displayed as a property of any other class.

9 views (last 30 days)
Hi,
I wrote a custom datetime class, because built-in datetime is often too slow.
My class inherits from matlab.mixin.CustomDisplay so that I can modify how it displays in the terminal. In particular I want to modify how it shows up within the displaying of some (any) other class to which it is a property.
I.e. let there be a class x.m with a property
dtime (1,1) my.datetime = my.datetime(now)
Now, if I display an instance of x.m in the terminal, it will show something like:
x with properties:
dtime: [1x1 my.datetime]
...
What I want it to look like is
x with properties:
dtime: 08.03.2020 17:39
...
where that datestring corresponds to a (dependent) property of +my/datetime.m.
The built-in datetime does something like that! How I can achieve this??
Thanks,
Niko
  7 Comments
Nikolaus Koopmann
Nikolaus Koopmann on 19 Mar 2020
oh really?! nice! this comes just in time.. i was about to rewrite A LOT of code back to datenums..
thanks!
Siddharth Bhutiya
Siddharth Bhutiya on 19 Mar 2020
As Guillaume mentioned, there have been some perfromance improvements to datetime/durations, specifically in subscripted assignment and text parsing in 2019b and 2020a. You can read about it here.
@Nikolaus If you could share some samples of performance bottleneck use cases that you mentioned, I can see if there are any improvements that can be made, so that you can avoid rewriting your exisinting code.

Sign in to comment.

Accepted Answer

Jennifer Black
Jennifer Black on 22 Apr 2022
As of R2022a, MATLAB provides a mixin class CustomCompactDisplayProvider for customizing the way instances of your class will display when held as values within some other container, such as a struct, cell array, or other object.
To support a custom contained display format for the custom datetime example, add this code to your class:
classdef mydatetime < matlab.mixin.CustomCompactDisplayProvider
...
methods
function rep = compactRepresentationForSingleLine(obj, configuration, width)
...
end
end
...
end
When an instance of your class is being displayed within a cell of a cell array, a field of a struct, or a property of some other object, MATLAB will invoke the compactRepresentationForSingleLine method. In your implementation, return a string representation of how you want your object to be displayed. Make sure that your string is no longer than the specified width input value.
Please see our documentation page for more details and an example of how to make use of the new interface.

More Answers (1)

Guillaume
Guillaume on 9 Mar 2020
"I can make my class inherit from your mentioned parent classes, but i cannot view those classes.. so there is no way of finding out which method to overwrite i guess?"
First, I've never tried to override the display of classes as you want to do, so disclaimer: I've no idea if matlab.mixin.internal.MatrixDisplay allows you to do that or not.
Yes, there is a way of finding out all the methods of the class as well as their signature, attributes and names of inputs and outputs. There is however no way to see their source code so you still have to do a fair amount of reverse engineering.
mc = meta.class.fromName('matlab.mixin.internal.MatrixDisplay') %obtain reflection information of the class
mc.MethodList is an array of meta.method objects describing all the methods of the class (included private/protected/hidden methods). You can see that there is one abstract method disp (public, hidden) which takes two inputs helpfully named rhs1 and rhs2. You probably also need to override displayImpl (protected, hidden) which also takes two inputs.
Another disclaimer: The above is valid in R2019b. None of these classes are documented so they can change/disappear in the next version. If you have access to the R2020a pre-release, I'd strongly recommend having a look at the parent classes of datetime. Unfortunately, we're not allowed to discuss the pre-release.
  3 Comments
Guillaume
Guillaume on 10 Mar 2020
Indeed, after some testing it doesn't appear that this kind of display is implemented by matlab.mixin.internal.MatrixDisplay. In fact, I'm not sure what kind of display it implements.
I've modified your original X to:
classdef X < handle & matlab.mixin.CustomDisplay
properties
dt datetime
qdt qdatetime
qdts qdatetime
end
methods
function obj = X()
obj.dt = datetime(2000,1,1);
obj.qdt = qdatetime(datenum(obj.dt));
obj.qdts = [obj.qdt obj.qdt];
end
end
methods (Access = protected)
function displayScalarObject(this)
displayScalarObject@matlab.mixin.CustomDisplay(this);
end
end
end
and by setting a break point in the displayScalarObject method, you can then step through what is happening during the display. In particular, you can see which datetime methods are called. There's only two methods that are called, the datetime.size method, which is normal it also happens with qdatetime and the datetime.cellstr method which is unexpected. Unfortunately, even if you implement a qdatetime.cellstr it doesn't get called automatically. This leads me to believe that the display of datetime within objects is actually hardcoded in matlab, so I'm afraid that it doesn't look like there's any way to implement the same.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!