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

Diagramming for Java Swing 4.0.1

MindFusion has released a new version of its Diagramming component for Java Swing with various new appearance and layout features. Here are the details:

Preserve order in tree layout

The new Balance property can be set to Preserve to keep the original geometric order of child nodes when arranging them under their parent. This can be used to arrange tree branches in a specific order by first placing them in increasing horizontal or vertical positions.

The tree layout algorithm

The tree layout algorithm

Undirected Path Finding

PathFinder supports undirected mode. Its methods have been changed from static to instance, and its constructor takes an ignoreDirection parameter. If ignoreDirection is enabled, the underlying graph is treated as undirected and link direction is not considered when looking for paths.

Detecting a cycle in a graph.

Detecting a cycle in a graph.

Selection Improvements

Miscellaneous

  • Style classes now contain a FontUnit property specifying the unit of measure of FontSize.
  • The last row in a TableNode will now be rendered clipped if it fits only partially inside the node, whereas in previous versions the row would not be rendered at all.
  • The AllowAddChildren and AllowRemoveChildren properties of ContainerNode specify whether users are allowed to add or remove child nodes to / from the container.
  • and many more.

You can learn more about the new JDiagram 4.0.1 at the news page on MindFusion’s forum. You can download the trial version of the control from the link below:

Download MindFusion.Diagramming for Java Swing 4.0.1

Technical support

Your questions about the diagramming library or any other of our components are welcomed by our support team. You can write at the forum, help desk or at support@mindfusion.eu.

About Diagramming for Java Swing: JDiagram provides your Java Swing application with all necessary functionality to create and customize a diagram. The library is very easy to integrate and program. There are numerous utility methods, rich event set, more than 80 predefined shapes. The tool supports a variety of ways to render or export the diagram, advanced node types like TreeView nodes, hierarchical nodes, tables, container nodes and many more. There are 15 automatic layouts, various input / output options and fully customizable appearance. A detailed list with JDiagram’s features is uploaded here. You can check the online demo to see some of the functionality implemented.

JDiagram is royalty free, there are no distribution fees. Licenses depend on the count of developers using the tool – check here the prices.