Custom Painting of Resources in Java Scheduler

In this blog post we will explain how to color cells and resources in the Resource view of the calendar based on a certain criteria. In our case we take the “Resource Table” sample from the Samples for the Java Swing Scheduler and we will edit its code to color the header and background of cells that correspond to given resources, in our sample it is an employee:

We will also add tooltips that show when the mouse is over cells that correspond to this employee:

I. General Settings

The code that we will demonstrate and explain is an extension to the “Resource Table” sample, which you can download from:

Download Resource Table Java Scheduler Sample

The sample uses the Scheduling Library for Java Swing, which is included as a Jar reference to the project.

We create an instance of the Calendar class and set its current time, date and the end date – this is the final date that will be visible in the resource view:

calendar = new Calendar();
calendar.setCurrentTime(DateTime.now());
calendar.setDate(new DateTime(2020, 6, 8));
calendar.setEndDate(new DateTime(2020, 7, 7));

The Calendar class exposes many methods for customizing the schedule. We first set the view to be CalendarView itemSettings and resourceViewSettings classes provide us with lots of options to customize the calendar look. We use them to twist the appearance of our resource table:

calendar.getItemSettings().getSelectedItemStyle().setHeaderFont(new Font("Verdana", Font.PLAIN, 9));
calendar.getItemSettings().getSelectedItemStyle().setHeaderTextAlignment(EnumSet.of(TextAlignment.MiddleLeft));
calendar.getItemSettings().getSelectedItemStyle().setHeaderTextShadowStyle(ShadowStyle.None);
...........................
...........................
calendar.getItemSettings().getStyle().setHeaderFont(new Font("Verdana", Font.PLAIN, 9));
calendar.getItemSettings().getStyle().setHeaderTextAlignment(EnumSet.of(TextAlignment.MiddleLeft));
calendar.getItemSettings().getStyle().setHeaderTextShadowStyle(ShadowStyle.None);
calendar.getItemSettings().getStyle().setHeaderTextShadowOffset(0);
...........................
...........................
calendar.getResourceViewSettings().getBottomTimelineSettings().setFormat("EEE (MM/dd)");
calendar.getResourceViewSettings().getBottomTimelineSettings().setSize(15);
calendar.getResourceViewSettings().getBottomTimelineSettings().getStyle().setHeaderBrush(Brushes.White);
calendar.getResourceViewSettings().getBottomTimelineSettings().getStyle().setHeaderFont(new Font("Verdana", Font.BOLD, 10));

The employees are instances of the Contact class. We add them to the contacts collection of the Calendar, once we’ve created them. It is important that we provide an id to each Contact, because that’s how we will identify them later in code:

Contact contact = new Contact();
contact.setFirstName("Mike");
contact.setId("IdMike");
contact.setName("Mike");
calendar.getContacts().add(contact);

The items that represent tasks for the resources are Appointment instances. We create them in code and add them to the items collection of the Calendar app;

app = new Appointment();
app.setStartTime(new DateTime(2006, 3, 27));
app.setEndTime(new DateTime(2006, 3, 28));
app.getContacts().add(calendar.getSchedule().getContacts().get("IdMike"));
app.setHeaderText("21965 Carbon Mesa Rd (1)");
app.setPriority(0);
calendar.getSchedule().getItems().add(app);

The resource view renders rows of cells that correspond to a given Resource, Location, Item, Task etc. The options available are members of the GroupType enumeration. In our sample we group the view by resources e.g. employees:

calendar.setGroupType(GroupType.GroupByContacts);

And with that we’ve finished with the general settings and we continue writing the code that will customize our application.

II. Custom Drawing

What we want to achieve as appearance of our resource table – selective coloring of the background of cells – can be done through custom drawing. Custom drawing provides us with means to color most elements of the calendar, depending on the view. The “Custom Draw Elements” sample gives us visual representation of the elements that correspond to the CustomDrawElements enumeration, which determines what is to be custom drawn in a schedule:

The sample is available from this link:

Java Swing Scheduler: Sample that Demonstrates the Custom Draw Elements according to the Calendar View

We want to color the resource header and the cells that correspond to this resource. So we use the setCustomDraw method to achieve that:

calendar.setCustomDraw(EnumSet.of(CustomDrawElements.ResourceViewRowHeader, CustomDrawElements.ResourceViewCellComplete));

The members of the CustomDrawElements enumeration allow bitwise combining. The drawing is done in an event handler for the draw event:

calendar.addCalendarListener(new CalendarAdapter() {
	public void draw(CalendarDrawEvent e) {
		onCalendarDraw(e);
	}
});

We use a CalendarAdapter to subscribe to the draw event, which we handle with the onCalendarDraw method. The CalendarDrawEvent class exposes many properties that give us information about the element that is being drawn. We use the getElement method to check, which element is being drawn – the cell or the header. If it is the cell, we get the resource that correspond to it and if it is the right one, we paint a rectangle, which represents the whole area of the element that is painted at the moment. We get it with the getBounds method:

if (e.getElement() == CustomDrawElements.ResourceViewCellComplete)
{
	Rectangle bounds = new Rectangle(e.getBounds());
	bounds.x += 1;

if (e.getResource().getId().equals("IdMike") ||
    e.getResource().getId().equals("IdChuck") ||
    e.getResource().getId().equals("IdTom") ||
    e.getResource().getId().equals("IdAlfredo"))
				
{
	g.fillRectangle(_brush3, bounds);
	g.drawString("Office", _font, _textBrush, bounds, f);
}

We will draw an outline to the resource header that correspond to the same resource, whose rows we colored with _brush3:

else if (e.getElement() == CustomDrawElements.ResourceViewRowHeader)
	{
		if (e.getResource().getId().equals("IdMike") ||
			e.getResource().getId().equals("IdChuck") ||
			e.getResource().getId().equals("IdTom") ||
			e.getResource().getId().equals("IdAlfredo"))
					
		{
			Brush _brush3 = new SolidBrush(new Color(254, 249, 207, 100));
			g.fillRectangle(_brush3, e.getBounds());
			g.drawRectangle(new Pen(new Color(163, 198, 134, 255), 2),
				e.getBounds().getMinX() + 1,
				e.getBounds().getMinY() + 1,
				e.getBounds().getMaxX() - 2,
				e.getBounds().getMaxY() - 2);
		}
			
	}

Here we check if the custom draw element is CustomDrawElements The CalendarDrawEvent class, which provides data for the event gives us sufficient information to recognize the exact element that is being painted.

III. Tooltips Over Selected Resources

By default the Calendar provides tooltips for items. The ItemTooltipEvent provides more information about this. However, we want to show tooltips when the user hovers over cells that correspond to the elements that we’ve painted in section II. We can do that by using a MouseMotionListener and subscribing to the mouseMove event. Note that these are standard Java Swing events:

calendar.addMouseMotionListener(new MouseAdapter() {
	public void mouseMoved(MouseEvent e) {
		onCalendarMouseMoved(e);
     }
		
});

In the event handler method we use the getResourceAt method of the Calendar to learn the resource, over which the mouse is hovering. Then we use the id-s that we’ve assigned to our resources and check if the mouse is over the resources that we want to render tooltips:

private void onCalendarMouseMoved(MouseEvent e) {
		
		Resource res = calendar.getResourceAt(e.getX(), e.getY());
		
		if (res.getId().equals("IdMike") ||
		    res.getId().equals("IdChuck") ||
		    res.getId().equals("IdTom") ||
		    res.getId().equals("IdAlfredo"))
		{				
			   calendar.setToolTipText(res.getId());				
				
		}
		else
		{
		     calendar.setToolTipText("");		    
		}			
		
}

When we detect that the mouse is over a resource that does not need to render tooltip, we set the tolltip text to be an empty string.

With that we’ve finished customizing the resource sample. You can download the extended version from this link:

Resource Table in Java Swing with Tooltips and Resource Coloring: Download

You are welcome to post your questions and comments at the Online Forum for Scheduling for Java Swing.

About MindFusion Scheduling for Java Swing: The library provides extensive feature-set for creating and customizing all sorts of calendars, task lists, time-management tables, resource allocation tables and other. It boasts various options for customizing appearance and numerous events for handling user actions. The distribution archive includes a lot of samples and detailed documentation. Learn more at https://mindfusion.eu/java-scheduler.html