Binding the Java Planner to Microsoft SQL Server Using JDBC

In this blog post we will bind to an MS SQL database called bookings. There we will select all data from a table named booking_data. The data is DateTime values. We will use the values to change the background of corresponding calendar cells in a simple Java application. The Java application renders a single-month calendar built with MindFusion Scheduler for Java library.

I. MS SQL EXPRESS Server Configuration

We download and install MS SQL EXPRESS server from https://www.microsoft.com/en-us/sql-server/sql-server-downloads. The installation also includes an application called “Sql Server Configuration Manager”. We start that application and click on the “SQL Services” tab. There we need to make sure that two services are running:

  • SQL Server
  • SQL Server Browser

You start these services by pressing the arrows in the toolbar at the top. If you cannot do this you need to change the Start Mode for this service. Double click it and in the Properties dialog that appears click on the “Service” tab. There you will find the “Start Mode” property and change it to “Manual”. Once you’ve done this you can start, stop or pause the service from the toolbar icons.

SQL Server Config Manager: Services

In order to start an SQL Server Service you might have to change its Start Mode to “Manual”.

Then we click on the “SQL Native Client” node and we select the “Client Protocols” tab. We make sure the TCP/IP Protocol is enabled.

SQL Server Config Manager: Enable TCP/IP

Make sure the TCP/IP protocol is enabled for the JDBC connection to succeed

The next step is to download Microsoft SQL Server Management Studio from https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-2017

Once we install it and start it we can create a new database called bookings. We right click on the Databases menu and choose “New Database”. We call it “bookings”. Then we expand the tree under “bookings” and right click on the “Tables” node. A window opens where we can define the columns for our new table. We add two columns:

  • id of type integer, which we set at primary key by right-clicking on it.
  • booked_date of type DateTime which will hold the dates that are booked.
Create a new table using MS SQL Server Management Studio

MS SQL Server management Studio: the dialog for defining a new table

After we are done we choose save and at this point we can provide a name for our table. We call it booking_data. With the table defined we right-click on it and choose “Edit Top 200 Rows”. There we add just three days (Jan 16th, Jan 22nd, Jan 26th) all of which in the current month. The data is auto-saved.

MS SQL Server management Studio: Table Edit

MS SQL Server Management Studio: here is how you edit the table data

The next step is to create a new user that will connect to this database. We click the “Security” node on the navigation tree and then “Logins”. Right-click and we choose “New Login”. In the dialog that opens we provide username and password. In order to do that we need to have the Login method set to “SQL Server authentication”. In the next tab “Server Roles” the new user must have “public” role. Then in “User Mapping” we tick the “bookings” database. In the Securables tab in the “Grant” grant column for the user we tick the “Connect SQL” permission. Then we close the dialog.

Grant SQL Connect to a DB User

Grant the new user the right to perform an SQL connection.

We get back to the bookings database and right-click on it. We choose “Properties” and from the dialog we click on the “Permissions” menu. There we select the user we’ve just created and in the Grant column of the underlying table we grant her the “Select” permission.

Granting User Permissions

Grant the DB user ‘Select’ permission to perform the required SQL query

With that the setup of our server and user is ready.

II. JDBC Driver & MS SQL Express Connection Properties

We download Microsoft’s JDBC Driver for MS SQL Server from this link: https://docs.microsoft.com/en-us/sql/connect/jdbc/microsoft-jdbc-driver-for-sql-server?view=sql-server-2017 and extract it. Next we create a new Java project. For this project we’ve used IntelliJ IDEA but any other Java IDE will do. In the project tree to the right we create a subfolder that we call “libs”. There we copy the jar of JDBC driver from the folder where we extracted it. Microsoft provides two versions of the driver depending on the JRE that you use. In our case we choose the version for JRE 10, which is called mssql-jdbc-7.0.0.jre10.jar. Next we right-click on the name of our project and select “Open Module Properties”. In the dialog we choose the “Modules” menu and there we click on the “Dependencies” tab and select the mssql-jdbc-7.0.0.jre10.jar module.

Configuring IntelliJ Project Modules

Configuring the IntelliJ Project to include the JDBC driver module

We click on the src folder of the project and add a new class, which we call MainWindow.java. In it we write the method establishConnection. This method is responsible for connecting to the MS SQL database “bookings”. Here is the code that makes the connection:

private void establishConnection() throws ClassNotFoundException
{

Connection conn = null;
PreparedStatement pst;

try {
// db parameters
String sql = "SELECT booked_date FROM booking_data";

String userName = "mindfusion";
String password = "mf123";

String url = "jdbc:sqlserver://DESKTOP-NV9S0TU\\SQLEXPRESS;databaseName=bookings;";

Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
conn = DriverManager.getConnection(url, userName, password);

pst = conn.prepareStatement(sql);
ResultSet rs = pst.executeQuery();

If you’ve followed strictly the steps we’ve outlined so far at this point you would successfully connect to your MS SQL Server with the credentials you’ve set up following the guide so far.

III. The Schedule Application

We download MindFusion Java Swing Scheduler from https://mindfusion.eu/java-scheduler.html and unzip it. We copy JPlanner.jar in the libs folder of the project and add it as a project dependency from the “Open Module Settings” menu. Then we define a Calendar variable and assign it to a new instance of the Calendar class.

public MainWindow() throws ClassNotFoundException
{
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(368, 362);
setTitle("MindFusion.Scheduling Sample: Minimal Application");

calendar = new Calendar();
calendar.setTheme(ThemeType.Light);
..................
..................
..................

establishConnection();
}

private Calendar calendar;

At the end of the method we call establishConnection and connect to the MS SQL Server.

IV. Styling the Calendar Dates

The aim of our sample application shall be to color those cells of the calendar that correspond to the dates we’ve read from the database. In order to do this we use the DateStyle class that sets some useful appearance properties to a range of cells that are specified with the setFrom and setTo methods. We use setBrush to change the background of the cell.

while (rs.next()) {
System.out.println(rs.getString("booked_date"));
Date date = rs.getDate("booked_date");

DateStyle dStyle = new DateStyle();
dStyle.setFrom(new DateTime(date));
dStyle.setTo(new DateTime(date));
Style style = new Style();
style.setBrush(new SolidBrush(Color.pink));
dStyle.setStyle(style);

calendar.getDayStyles().add(dStyle);

}

Finally we add the style to the DayStyles collection of the calendar.

Here is the final application:

Scheduling application in Java Swing with MS SQL Server JDBC Connection

MindFusion Java Swing application with the Scheduling library and MS SQL Server

You can download the project together with the MS SQL Server JDBC driver library and the scheduling library from this link:

Download JPlanner Sample Application That Uses MS SQL Server JDBC Connection

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 extensive documentation. Learn more at https://mindfusion.eu/java-scheduler.html

Interactive Event Timetable in JavaScript

This blog post describes the main steps on how to create a schedule table, which shows the allocation of college rooms to different courses. Users can filter the courses by lecturer(s).

I. Initial Setup

We start by copying the JavaScript scheduler files that we’ll use in the directory of our project. These are:

  • MindFusion.Scheduling.js – represents the Js Scheduler library
  • MindFusion.Scheduling-vsdoc.js – provides Intellisense support
    standard.css – in a subdirectory “themes”, this is the CSS theme styling of the resource table
  • planner_lic.txt – paste your license key here to disable the trial version label.

We create then 2 more files specifically for our application:

  • ResourceView.html – the web page of the application
  • ResourceView.js – the JavaScript code that implements the dynamic features of our application.

II. The HTML Page

In the head section of our web page we first create a reference to the theme file:

 	 	<link rel="stylesheet" type="text/css" href="themes/standard.css">

At the end of the web page, just before the closing </body> tag we add a reference to the Scheduling.js file that contains the scheduling features and the ResourceView.js files that we’ll write for the application:

<script src="MindFusion.Scheduling.js" type="text/javascript"></script>
<script src="ResourceView.js" type="text/javascript"></script>

The calendar library requires an HTML <div> element, which is used to render it. We add one:

<div id="calendar" style="height: 100%; width: 100%;"></div>

It is important that you add an id to this <div> because we need to reference it in the JS code behind file.

III. Basic JavaScript Settings

At the top of the JavaScript code-behind file we add a reference to the Intellisense file. We also create a mapping to MindFusion.Scheduling namespace:

/// <reference path="MindFusion.Scheduling-vsdoc.js"></reference>
var p = MindFusion.Scheduling

Then we create the calendar object. We need a reference to the <div> element that will render it:

// create a new instance of the calendar
calendar = new p.Calendar(document.getElementById("calendar"));

For this sample we will use the ResourceView The currentView property specifies that. In addition, we set the count of visible cells in the calendar to 7. That is done through the resourceViewSettings property of the calendar

// set the view to ResourceView, which displays the distribution of resources over a period of time
calendar.currentView = p.CalendarView.ResourceView;

// set the number of visible cells to 7
calendar.resourceViewSettings.visibleCells = 7;

The itemSettings proeprty lets us customize the items in the schedule We use titleFormat and tooltipFormat to specify how the title and tooltip of each item will be rendered. Both properties use special format strings:

  • %s – the start date will be rendered
  • %e – the end date of the item will be rendered
  • %d – the details of the item will be rendered.

You can specify the way dates and time are formatted by adding the desired format in brackets:

// show hours on items
calendar.itemSettings.titleFormat = "%s[HH:mm] - %e[HH:mm] %h";
calendar.itemSettings.tooltipFormat = "%d";

Then we set the theme of the calendar to standard, whose css file we referenced in the web page:

calendar.theme = "standard";

and we make one more adjustment – the name of contacts will be taken from the last name of the person. Possible valies are “F”, “M” and “L” – for first, middle and last name.

calendar.contactNameFormat = "L";

IV. Resources

When the calendar initially loads there are several contacts and locations available. The objects that represent them are instances of the Contact and Location classes. After we create them we add them to the contacts and locations collections of the calendar schedule.

var resource;

// Add professor names to the schedule.contacts collection.
resource = new p.Contact();
resource.firstName = "Prof. William";
resource.lastName = "Dyer";
calendar.schedule.contacts.add(resource);

resource = new p.Location();
resource.name = "Room D";
calendar.schedule.locations.add(resource);

Now, when the user creates a new course they will see the Contact and Location in the Options pane of the “Create Item” form:

V. Items

The items are instances of the Item class. They represent the classes of the different lecturers. We use the startTime and endTime properties of Item to specify when the class takes place. The subject property gives the name of the class:

//always start with the current date
var date = p.DateTime.today();

item = new p.Item();
item.startTime = p.DateTime.addHours(date.addDays(1), 14);
item.endTime = p.DateTime.addHours(item.startTime, 1);
item.subject = "Classical Mechanics";

We use the location and contacts properties to set where the lecture takes place and who teaches it. Note that the contacts property is of type collection and we can assign several lecturers to one class:

item.location = calendar.schedule.locations.items()[0];
item.contacts.add(calendar.schedule.contacts.items()[0]);

We get the location and the contact from the schedule’s lists with locations and contacts We must also set the details of the item – they will be rendered as a tooltip, if you remember. We want the tooltip to show the two names of the lecturer and the location. Here is how we must define it:

item.details = item.contacts.items()[0].firstName + " " +
item.contacts.items()[0].lastName + " - " + item.location.name;

We must add the item to the items collection of the schedule we render the calendar render the calendar

calendar.render();

VI. Events

When users create new items we must set their details to tell the name and the location of the new class. We handle the itemCreating event to do this:

// attach handler - creating an item
calendar.itemCreating.addEventListener(handleItemCreating); 

function handleItemCreating(sender, args) {
    handleItemModified(sender, args);
    if (args.item.contacts.count() &gt; 0) {
        //the details field is used by the tooltip
        args.item.details = args.item.contacts.items()[0].firstName + " " +
                args.item.contacts.items()[0].lastName;

        if (args.item.location != null)
            args.item.details += " - " + args.item.location.name;
    }

}

The itemCreating event provides an instance of the ItemModifyingEventArgs class as a second argument to the handler method. There we use the item property that tells us which item is being modified. We then take the desired contact and Location information from the contacts and location properties of the item.

When a new course item is dragged to another location we must change its color accordingly. We do this by handling the itemModified event.

// attach handler - modifying an item
calendar.itemModified.addEventListener(handleItemModified);

The diferent background color of the items is achieved by custom CSS classes. We use the cssClass property of the Item class. The CSS styles are defined in the <HEAD> section of the web page:

 .mfp-planner.standard .itemClass1 .mfp-item {
            background-color: 	#0c71af;
        }

.mfp-planner.standard .itemClass2 .mfp-item {
            background-color: #f81e1e;
        }
...........

The handler method checks the new location and assigns the appropriate CSS style:

function handleItemModified(sender, args)
{
    // you don't have to check any other conditions like dragging to another room, 
    // as it will stay the same color if you make other changes (other than dragging to a different room)
    if (args.item != null){
        switch (args.item.location.name) {
            case "Room A":  //we can also implement it with for
                args.item.cssClass = 'itemClass1';
                console.log("a");
                break;
            case "Room B":
                args.item.cssClass = 'itemClass2';
                break;
            case "Room C":
                args.item.cssClass = 'itemClass3';
                break;
            case "Room D":
                args.item.cssClass = 'itemClass1';
                break;
            case "Room E":
                args.item.cssClass = 'itemClass2';
                break;
            case "Room F":
                args.item.cssClass = 'itemClass3';
                break;
            default:
                args.item.cssClass = 'itemClass1';
        }
    }
}

The item property of the args parameter of the handler method provides access to the item that was modified.

VII. Filtering Professors

We want to add one last feature to our application. We want the user to be able to render courses only by a given professor.

We first add checkboxes with the names of the lecturers. Each checkbox has the same handler method for the click event:

<input id="dyer" checked="checked" name="subscribe" type="checkbox" value="Dyer>
<label for=">Prof. William Dyer

<input id="fletcher" checked="checked" name="subscribe" type="checkbox" value="Fletcher">
<label for="fletcher">Prof. Ann Fletcher</label>
...........................

The handler method needs to look at two cases. The first case is when the class is taught by a single professor. In this case we cycle through all items and make the item visible or not depending on whether the check box with the name of the professor is checked:

// if there is at least one present professor from the lecture professors, the lecture will not disappear
function handleClick(cb) {
for (var i = 0; i &lt; calendar.schedule.items.count(); i++) {
        var item = calendar.schedule.items.items()[i]; //we iterate through every element
        if (item.contacts.count() == 1) {
            if (item.contacts.items()[0].lastName == cb.value)
                item.visible = cb.checked;
        }
      }
.......................
}

In the second case we look at courses that are taught by more than one lecturer. In this case we show the item if the checkbox with the name of at least one of the lecturers is selected:

else if (item.contacts.count() &gt; 1) {
for (var j = 0; j &lt; item.contacts.count() ; j++) {
                if (item.contacts.items()[j].lastName == cb.value) { // the checked/unchecked professor is in the contacts of this item
                    if (cb.checked == true) item.visible = true; // if there is a check, the item must be visible
                    else { // if there is no check, we see if there is at least one professor in the list of contacts of the item
                        item.visible = professorPresent(item);
                    }

                }
            }
        }

Finally we repaint the calendar:

// repaint the calendar
this.calendar.repaint(true);

Here the professorPresent method checks if at least one of the check boxes with professors that are present as lecturers in the item that we provide as argument are selected:

// return true if even 1 professor from the item's contacts is present, false otherwise
function professorPresent(item) {
    console.log(item.contacts.count());
    for (var j = 0; j &lt; item.contacts.count() ; j++) {
        var checkBoxId = item.contacts.items()[j].lastName.toLowerCase();
        var checkBox = document.getElementById(checkBoxId);
        if (checkBox!= null &amp;&amp; checkBox.checked == true) {
            return true;
        }
    }
    return false;
}

And that’s the end of this blog post. Here is a link to download the complete source code of this application:

Download The Sample Resource View Application

About MindFusion JavaScript Scheduler: MindFusion Js Scheduler is the complete solution for all applications that need to render interactive timetables, event schedules or appointment calendars. Fully responsive, highly customizable and easy to integrate, you can quickly program the JavaScript scheduling library according to your needs. Find out more at https://mindfusion.eu/javascript-scheduler.html

Interactive Calendar With Events In JavaScript

In this blog post we will create a Google-like interactive monthly calendar where users will be able to create, edit and delete appointments in real time. We
will use the JavaScript Scheduler. Here is a screenshot of the finished application:

JavaScript Schedule That Mirrors the Google Calendar Features

JavaScript Schedule That Mirrors the Google Calendar Features

And you can run the sample online from this link.

I. Project Setup

We need a reference to the following file to start development:

  • MindFusion.Scheduling.js
  • light.css

The JavaScript file provides the scheduling functionality. The CSS file is responsible for the styling of our calendar. We create a subfolder named “themes” and we place the light.css file there.

We create an HTML file, a blank web page called GoogleSchedule and in the head section we place a reference to the two CSS file:

<link href="themes/light.css" rel="stylesheet" />

 

The reference to the JavaScript file goes at the bottom of the page, right before the closing body tag.

<a href="http://MindFusion.Scheduling.js">http://MindFusion.Scheduling.js</a>

 

We need a element that will represent the calendar, we create one in HTML code and assign it an id:

<div id="calendar" style="height: 100%; width: 100%;"></div>

We want the calendar to take the whole page, that’s why width and height are 100%.

II. Create and Customize the Scheduler

Now we are ready to do the real JavaScript programming of the calendar library. We create an empty JS file called “GoogleSchedule.js” and add a reference to it in the web page, at the bottom:

<a href="http://GoogleSchedule.js">http://GoogleSchedule.js</a>

 

In this JavaScript file we first create a mapping to the MindFusion.Scheduling namespace:

var p = MindFusion.Scheduling;

 

Then we create a Calendar instance using the Calendar DOM element from the web page:

// create a new instance of the calendar 
var calendar = new p.Calendar(document.getElementById("calendar"));

 

We set the calendar view to CalendarView .SingleMonth, which means the calendar shows one month at a time. We also set the theme that we referenced in the CSS file:

calendar.currentView = p.CalendarView.SingleMonth;
calendar.theme = "light";

 

Another customization we make – we use the itemSettings.titleFormat property to add a prefix before each event subject. The prefix is the start time of this event. here is how you set it:

calendar.itemSettings.titleFormat = "%s[hh:mm tt] %h";

 

Finally, we render the calendar:

//visualize the calendar
calendar.render();

 

III. Custom Form

By default, the form that renders when the user clicks on a cell or selection of cells in the calendar allows edit of the dates, but not hours. We will render our custom form, derived from BaseForm to change that. Our form will offer the users a list with hours for the selected dates.

We create a new, empty JavaScript file “TimeForm.js”. There we override the constructor of the BaseForm:

 TimeForm = function (calendar, item, type)
{
	p.BaseForm.call(this, calendar, item);

	this._id = "TimeForm";
	this._type = type;
	this.headerText = "Appointment";
	
}

 

As you can see from the constructor each BaseForm provides data for the calendar and the item that is created or edited. We will use that information later on. We create a prototype of our form and assign the constructor:

TimeForm.prototype = Object.create(p.BaseForm.prototype);
TimeForm.prototype.constructor = TimeForm;

 

TimeForm will be a simple one – it just renders a text area and two combo boxes with the possible hours for the start and end of the appointment. The combo boxes require a list with the members to be rendered. We create a list as a global variable:

var hoursList;

 

Then, in a new method we fill the list with the hours from 12 to 1, divided in intervals of 30 minutes:

// create an array of objects to fill the hours drop-down
TimeForm.prototype.getHourLabels = function ()
{
	hoursList = [];
	hoursList.push({ value: 0, text: "12:00am" });
	hoursList.push({ value: 1, text: "12:30am" });
	
	let index = 1;
	
	for(var i = 1; i &lt; 12; i++)
	{
		hoursList.push({ value: index+1, text: i.toString() + ":00am" });
	    hoursList.push({ value: index+2, text: i.toString() + ":30am" });
		
		index += 2;
	}
	
	//add the first afternnon hours
	hoursList.push({ value: index + 1, text: "12:00pm" });
	hoursList.push({ value: index + 2, text: "12:30pm" });
	
	index += 2;
	
	for(i = 1; i &lt; 12; i++)
	{
		hoursList.push({ value: index+1, text: i.toString() + ":00pm" });
	    hoursList.push({ value: index+2, text: i.toString() + ":30pm" });
		
		index += 2;
	}	
	
	return hoursList;
}

 

The next step is to override the drawContent function of BaseForm:

TimeForm.prototype.drawContent = function ()
{
	p.BaseForm.prototype.drawContent.call(this);

	var content = this.getContent();
.....
}

 

First, we create the text area:

var row = this.row();
	row.innerHTML = this.localInfo.subjectCaption;
	content.appendChild(row);
	
	// create a text-area for the item subject
	var textArea = this.createTextArea({ id: "subject", initValue: this.item.subject, events: { keydown: this._areaKeyDown} });
	textArea.element.style.width = "200px";
	this.addControl(textArea);

	row = this.row();
	row.appendChild(textArea.element);
	content.appendChild(row);

 

Before the text area we place a label with “Subject” on it. The createTextArea method requires several parameters. The first one is the id, then the initial content to be rendered and the events. We want the text area to be 200px wide. The row element places a row of controls in the BaseForm. We use it every time we want to start a new row with elements.

The text area reads its initial content from the value of the subject field in the item object that we receive as reference. After that we create a new row with elements: the drop-down with the hours for the start time:

       // create a drop-down list for start hours
	row = this.row();
	row.innerHTML = "Start Time";
	content.appendChild(row);

	var control = this.createDropDownList({ id: "start_time", items: this.getHourLabels(), initValue: this.getStartTimeIndex(), addEmptyValue: false });
	control.element.style.width = "200px";
	this.addControl(control);

	row = this.row();
	row.appendChild(control.element);
	content.appendChild(row);

 

The code is almost identical to the code for the text area, but here we call the getHourLabels method that returns the array with time values. There is one other new method: getStartTimeIndex(). It’s task is to check the start time of the item and to set the initial value of the drop-down control to that time.

Here is the method:

// get the index of the current item's index to set the value of the startTime drop-down:
TimeForm.prototype.getStartTimeIndex = function ()
{
	if (this.item != null &amp;&amp; this.item.startTime != null)
	{
		
		let index  = this.item.startTime.__getHours() * 2;
		if(this.item.startTime.__getMinutes() &gt; 0)
			index++;
		return index;		
		
	}
	return -1;
}

 

The method checks the hour value of the start time and multiplies it by two because for each hour we show two values in the drop-down: 9:00 and 9:30. If the user has selected half an hour we increment the index with 1.
We use almost the same code to create the endTime drop-down control, so we won’t discuss it here. You can check its code from the download with the source code files for this sample.

Our form needs two buttons – Save and Cancel. We create them in the drawButtons method:

// override BaseForm's drawButtons method to create form buttons
TimeForm.prototype.drawButtons = function ()
{
	var thisObj = this;

	var btnSave = this.createButton({
		id: "btnSave",
		text: this.localInfo.saveButtonCaption,
		events: { "click": function click(e)
		{
			return thisObj.onSaveButtonClick(e);
		}
		}
	});

	var btnCancel = this.createButton({
		id: "btnCancel",
		text: this.localInfo.cancelButtonCaption,
		events: { click: function click(e)
		{
			return thisObj.onCancelButtonClick(e);
		}
		}
	});

	var buttons = this.row();
	buttons.classList.add("mfp-buttons-row");
	buttons.appendChild(btnSave.element);
	buttons.appendChild(btnCancel.element);

	return buttons;
};

 

The BaseForm.createButton() method is similar to the methods that create text area and drop-down lists. We specify here that we will handle the click event for the two buttons. We place the buttons in a new row. Note that you don’t have to call the createButtons function anywhere – it is called automatically by BaseForm.

What happens when the user presses “Save”? Well, we’ll have to read the data from the hour drop-down controls and adjust the start and end time of the newly created Item:

TimeForm.prototype.onSaveButtonClick = function (e)
{
	// update the item with the form data
	 // update the item with the form data
   var startIndex = +this.getControlValue("start_time");
   var startTime = this.item.startTime.date.clone().addHours(startIndex * 0.5);

   var endIndex = +this.getControlValue("end_time");
   var endTime = this.item.endTime.date.clone().addHours(endIndex * 0.5);

   // if end time is specified, decrease it by one day
   if (endIndex != 0 &amp;&amp; this.item.endTime.hour == 0)
    endTime.addDays(-1);

   // check for inconsistent start/end time
   if (startTime.valueOf() &gt; endTime.valueOf())
         endTime = startTime.clone().addHours(1);

   // apply changes 
   this.item.subject = this.getControlValue("subject"); 
   this.item.startTime = startTime;
   this.item.endTime = endTime;

   // if a new item is created, add it to the schedule.items collection
   if (this.type === "new")
     this.calendar.schedule.items.add(this.item);

   // close the form
   this.closeForm();

   // repaint the calendar
   this.calendar.repaint(true);
};

First, we get the value of the startTime drop-down list and we calculate the amount of time to add to the startTime of an Item. A new Item always has a startTime at midnight. Then, we check the number of days the user has selected and calculate how many hours the event actually takes. We assign end time to a copy of the start time and add the calculated event duration to the value. Finally, if the event is new – we add it to the collection of item sin the schedule, if it’s old – we correct its data. Then we close the form and repaint the calendar.

IV. Using the Custom TimeForm

In order to use our custom form we have to add a reference to it in the HTML page, as we did with the other two files:

<script src="TimeForm.js" type="text/javascript"></script>

 

Then we edit the GoogleSchedule.js file First, we need to disable the built-in forms with the useForms property.

// disable this built-in forms for item creation and modification
calendar.useForms = false;

 

Then we have to handle the onSelectionEnd and onItemDoubleClick events to render our form. First, we wire up the events:

// handle the itemDoubleClick event to show the custom form for item editing
calendar.itemDoubleClick.addEventListener(handleItemDoubleClick);

// handle the selectionEnd event to show the custom form for item creation
calendar.selectionEnd.addEventListener(handleSelectionEnd);

 

Then we render the forms, below is the code that shows the TimeForm when a new item is created:

function handleSelectionEnd(sender, args)
{
	// create a new item with the start and end time of the selection
	var item = new p.Item();
	item.startTime = args.startTime;
	item.endTime = args.endTime;
	
	// create and show the custom form
	var form = new TimeForm(sender, item, "new");
	form.showForm();
}

 

We copy the start and end time of the selection from the event arguments. Then we use them in the constructor of the BaseForm.

And that’s the end of this tutorial. Here is a link to download the complete source code of the sample:

Download the Google Calendar in JavaScript Sample

About MindFusion JavaScript Scheduler: MindFusion Js Scheduler is the complete solution for all applications that need to render interactive timetables, event schedules or appointment calendars. Fully responsive, highly customizable and easy to integrate, you can quickly program the JavaScript scheduling library according to your needs. Find out more at https://mindfusion.eu/javascript-scheduler.html

Ticket Booking System (Continued)

In part I of the Ticket Booking System blog post we discussed the controls used in the software and how we generate and arrange the hall seats. Now let’s get deeper into the details on how we retrieve the data and how we customize the controls.

We use the Entity Framework and the Entity Data Model wizard to connect to our MS SQL database and retrieve the ticket data. Here is the model of the database:

Event Booking Software: MS SQL Database Model

Event Booking Software: MS SQL Database Model

I. The Database

We have a table for the event type (ballet, concert, opera etc.), a table for the events (Swan Lake ballet, Mozart concert, La Traviata oepra etc.), a table for the performances (an event with a date) and a table for the tickets that were sold. The performance table has a column for the base price of the tickets. The hall is divided into 3 sections according to the price of the tickets – the Performance table stores the price for the cheapest category. The other two categories are calculated according to the base price.

II. Events

We keep a class variable for the EventsTicketsEntities, which we initialize in the Form1 constructor:


public partial class Form1 : Form
{
   EventsTicketsEntities records;
   double basePrice;

   public Form1()
   {
      InitializeComponent();
      records = new EventsTicketsEntities();
      .................
}

The events are instances of the Appointment class of the Calendar. Here is the method that we use to create the Appointment-s based on the data from the database:


private void loadEvents()
{         

  List performances = records.Performances.ToList();     

  foreach (Performance p in performances)
   {
      Appointment app = new Appointment();
      app.StartTime = (DateTime)p.Date;
      app.EndTime = app.StartTime.AddHours(2.0);           
      app.HeaderText = "";
      app.DescriptionText = p.Event.Title;
      app.Tag = p.Event.EventType_Id;
      app.Style.Brush = getBrush((int)app.Tag);
      calendar.Schedule.Items.Add(app);

     }
}
	

We read all records in the Performances table and create an Appointment for each one. The start date of the event is the field from the database. We add to it 2 hours as duration, otherwise the event wouldn’t show up. The brush of the Appointment depends on the type of the event. The appointment does not show any text, but the event title serves as a description. As a rule the calendar control renders an Appointment‘s description as a tooltip when the user hovers the item.

The schedule item description is rendered as a tooltip

The schedule item description is rendered as a tooltip

III. Hall Seats

In order to identify the location of a seat we assign an instance of the Seat structure as an Id to the ShapeNode that represents the seat.

public struct Seat
{
  public Seat (int row, int column)
   {
     this.Row = row;
     this.Place = column;
   }

  public int Row
   {
     get; set; 
   }

 public int Place
   {
       get; set;
   }

}

We also include a rowStart parameter in the CreateSection method. The parameter keeps track of the total count of seats being generated. This allows each seat to have a unique row number:

	

void CreateSection(int rowStart, int[] seatsPerRow,
    float topY, float seatWidth, float seatHeight,
     float xPadding, float yPadding, float arcRadius)
{
        .................		
 
        seat.Id = new Seat(rowStart + r, s);
        seat.Tag = calcSeatCoeff((Seat)seat.Id);	

}

The Seat tag of the ShapeNode is calculated based on its location in the hall. It is the coefficient, which multiplied by the base price for this performance gives us the final price for this seat.

Each time a new performance is selected on the calendar, our application must refresh the seat info. Here is the method that takes care of the seat colors:

//clears the X sign at an occupied seat
private void updateSeats( double basePrice )
{
  foreach( var seat in diagram.Nodes)
  {
     (seat as ShapeNode).Text = "";
     if (seat.Tag != null)
      {
        seat.Brush = getSeatBrush(basePrice * (double)seat.Tag);
       }
  }
}

The method calculates the price of the seat and checks the color that corresponds to this price. Whenever a seat is clicked, the application marks it as selected. This is done by drawing an “X” as text on the ShapeNode using a large Font size:

Seat seatInfo = (Seat)seat.Id;
TICKETS_SOLD _ticket = new TICKETS_SOLD() { };
_ticket.Id = records.TICKETS_SOLD.ToList().Count;
_ticket.Performance_Id = (int)calendar.Tag;
_ticket.Row_Index = seatInfo.Row;
_ticket.Seat_Index = seatInfo.Place;
records.TICKETS_SOLD.Add(_ticket);
                        
try
    {
      records.SaveChanges();

    }
catch (DbEntityValidationException ex)
    {
      Debug.WriteLine(ex.Message);
    }
    seat.Text = "X";

We create a new TICKETS_SOLD record, which contains a unique Id for the sold ticket, an Id for the performance, and the location of the seat (row and column). There is something more to that. When the user tries to click on a seat that is already sold we want to warn him that it is not possible to buy the seat. This is done by having a special node that stays hidden and shows up for a few seconds only to warn the user:

private void generateOccupiedNode()
  {
    float x = diagram.Bounds.Left + diagram.Bounds.Width / 2 - 50;
    float y = diagram.Bounds.Top + diagram.Bounds.Height / 2 - 30;

    RectangleF nodeBounds = new RectangleF(x, y, 100, 60);
    ShapeNode node = diagram.Factory.CreateShapeNode(nodeBounds);
    node.Brush = new MindFusion.Drawing.SolidBrush(Color.FromArgb(100, 206, 0, 0));            
    node.Font = new Font("Arial", 26);
    node.TextBrush = new MindFusion.Drawing.SolidBrush(Color.Black);
    node.Visible = false;
    node.Shape = Shapes.RoundRect;
    node.Id = "Occupied";

  }
		

The seat is rendered in the middle of the diagram’s visible area and has a semi – transparent background. We use a timer to track the seconds when the node is displayed:


private void diagram_NodeClicked(object sender, NodeEventArgs e)
 {
   ShapeNode seat = e.Node as ShapeNode;
   if(seat != null)
     {
       if(seat.Text == "X")
        {
           ShapeNode warning = (ShapeNode)diagram.FindNodeById("Occupied");

          if(warning != null)
          {
             warning.Text = "This Seat is Occupied!";
             Timer timer = new Timer();
             timer.Interval = 2500;
             timer.Tick += Timer_Tick;
             warning.Visible = true;
             timer.Start();
          }
        }
	...........
	
}

We then find the node and make it invisible again:


private void Timer_Tick(object sender, EventArgs e)
  {
    ShapeNode warning = (ShapeNode)diagram.FindNodeById("Occupied");
    warning.Visible = false;
}
     

With this we have covered the basic methods that build the Event Ticket Reservation Software. Here is the final version:

Event Booking System in WinForms

Event Booking System in WinForms

The full source code of the application together with the sample database is available for direct download from here:

Event Ticket Booking System – Download

The sample uses the Diagramming and Scheduling controls from the MindFusion WinForms Pack. If you have questions regarding the sample or the components do not hesitate to post them on the MindFusion discussion board.

Ticket Booking System

In this blog post we will create a sample ticketing software that will allow users to select events and book tickets for them. We will use the MindFusion Diagramming and Scheduling components for WinForms. The tutorial is divided int two parts:

I. The Controls

We create a WinForms application in VisualStudio and add a new folder ‘Assemblies’ with the dll-s that we want to use. There we copy:

  • MindFusion.Common.dll
  • MindFusion.Common.WinForms.dll
  • MindFusion.Diagramming.dll
  • MindFusion.Diagramming.WinForms.dll
  • MindFusion.Licensing.dll
  • MindFusion.Scheduling.dll

Then we click on the Toolbox pane -> Choose Items -> Browse and we add the MindFusion.Diagramming.WinForms and MindFusion.Scheduling dll-s. They add a list of components, but we select the DiagramView and the Calendar controls and drop them onto the form. The DiagramView creates automatically the diagram instance that it renders.

II. The Hall Layout

The hall layout is rendered by the flowchart control. We use a special method that we’ve named CreateSection to create and arrange a section in the hall. The declaration of the method is:

void CreateSection(int[] seatsPerRow,
            float topY, float seatWidth, float seatHeight,
            float xPadding, float yPadding, float arcRadius)

We provide the method with an array of integers that indicate the number of seats on each row in the section. Then is the offset to the top and the size of each seat. The xPadding and yPadding arguments indicate the space between two adjacent seats. The last argument indicates how curved the row of seats is.

What the method generally does is calculate the location of each seat and generate a node with these coordinates and given size:

 float y = topY;
     for (int r = seatsPerRow.Length - 1; r &gt;= 0; r--)
        {
           var c = new PointF(0, y + arcRadius);
           int seats = seatsPerRow[r];
           float rowWidth = seats * seatWidth + (seats - 1) * xPadding;
           float x = -rowWidth / 2;
     
           for (int s = 0; s  0)
                  {
                     float angle = 0;
                     float radius = 0;
                     MindFusion.Geometry.Geometry2D.Convert.CartesianToPolar(
                         c, new PointF(x, y), ref angle, ref radius);
                     adjustedY = c.Y - arcRadius * Math.Sin(angle * Math.PI / 180);
                  }
                 diagram.Factory.CreateShapeNode(
                     x, (float)adjustedY, seatWidth, seatHeight);
                     x += seatWidth + xPadding;
               }
               y += seatHeight + yPadding;
           }

The nodes are created with Factory.CreateShapeNode method which uses the Factory helper class of the diagram component. The CreateShapeNode method creates and adds the newly created nodes to the Nodes collection of the diagram.

III. The Calendar

The default settings of the Scheduling control give us exactly the month view with events we want to get. However we still need to add some customizations:

First, we won’t allow users to perform in-place edit of events on the calendar:

calendar.AllowInplaceEdit = false;

Then we will change the brushes for the calendar items and will hide the clock icons that appear at the header of events:

calendar.ItemSettings.Size = 10;            
calendar.ItemSettings.ShowClocks = MindFusion.Scheduling.WinForms.ShowClocks.Never;
calendar.ItemSettings.Style.Brush = new MindFusion.Drawing.SolidBrush (Color.FromArgb(102, 154, 204));
calendar.ItemSettings.Style.BorderBottomColor = calendar.ItemSettings.Style.BorderLeftColor =
                calendar.ItemSettings.Style.BorderRightColor = calendar.ItemSettings.Style.BorderTopColor = Color.FromArgb(192, 192, 192);
calendar.ItemSettings.SelectedItemStyle.Brush = new MindFusion.Drawing.SolidBrush (Color.FromArgb(206, 0, 0));
calendar.Selection.SelectedElementsStyle.Brush = new MindFusion.Drawing.SolidBrush(Color.FromArgb(224, 233, 233));

Now let’s create a few items:

Appointment event1 = new Appointment();
event1.StartTime = new DateTime(2017, 5, 2, 16, 0, 0);
event1.EndTime = new DateTime(2017, 5, 2, 18, 30, 0);
event1.HeaderText = "";
event1.DescriptionText = "Swan Lake";
event1.Tag = EventType.Ballet;
event1.Style.Brush = new MindFusion.Drawing.SolidBrush(Color.FromArgb(102, 154, 204));

calendar.Schedule.Items.Add(event1);

Our Appointment-s have a start and end time, description, brush according to the EventType and tag that indicates the type of event that is rendered. It would be nice to have tooltips that provide details about the event:

calendar.ShowToolTips = true;

This turns on tooltips on all calendar items. We want tooltips just on our events so we use the TooltipDisplaying event to hide the tooltips on items that are not events:

calendar.TooltipDisplaying += Calendar_TooltipDisplaying;
.....

}

private void Calendar_TooltipDisplaying(object sender, MindFusion.Scheduling.WinForms.TooltipEventArgs e)
{
  if(e.Element.GetType() != typeof(Appointment))
     {
       e.Tooltip = "";
     }
}

Here is a screenshot of the event ticketing system so far:

Event Ticket System with MindFusion WinForms Controls

Event Ticket System with MindFusion WinForms Controls

A download of the project with all necessary dll-s is available from this link:

Ticket Booking System in WinForms

The Scheduling for WinForms and Diagramming for WinForms components are part of MindFusion WinForms control suite – the perfect set of tools to help you build any type of WinForms software fast and easy. Find out more about MindFusion WinForms pack here.

MindFusion.WPF Pack, 2016.R1

The new release of MindFUsion WPF Control Suite lists many new features, aimed to empower developers to create compelling business applications with even less efforts. The pack also includes new samples and tutorials. Below are the details:

License keys
There is no separate trial build of the control assemblies anymore. Instead, set the LicenseKey property of the controls to disable their evaluation mode and stop displaying trial messages. If your application contains more than one control by MindFusion, you could call MindFusion.Licensing.LicenseManager.AddLicense(key) from application start-up code to specify the key once instead of setting it per each control.

Visual Studio 2015 support
MindFusion Pack for WPF now includes support for Visual Studio 2015. The installer can create VS2015 toolbox palette for the component.

Barcodes
The new BarcodeLabel class allow displaying EAN, UPC or QR barcodes.

BarcodeLabel: QR barcodes

BarcodeLabel: QR barcodes

MindFusion Chart ControlMindFusion.Charting for WPF

Multiple Axes
The chart control enables developers to create unlimited number of axes of each type – X, X2, Y and Y2. Each axis is an instance of the Axis class and has its own set of properties for complete customization – label style, brush, tick length etc. You can set the X and Y axes of each ChartSeries to a series of your choice and thus bind each chart series to different axes, if you wish.

Multiple axes in the WPF chart control.

Multiple axes in the WPF chart control.

Improved Zooming
Selected area with width smaller than MinZoomSpan does not evoke any action in the control. In addition, the new ZoomChanged event fires whenever zoom occurs and provides useful data for the zoom action with its ZoomChangedArgs.

Cross Hair Improvements
The cross hair control has been improved with several new properties, a method and an event. The properties are:

The new CrossHairPosition method returns the current location of the cross hair. For more precise handling of cross hair movements a new event is available – CrossHairPositionChanged.

Greatly Improved 3D Charts
3D charts have received plenty of improvements, new properties and performance optimizations:

  • PointMergeThreshold – The property sets the radius of an area around a given point where no other points are drawn. The result is better performance especially in charts with numerous points, which happen to be close to one another.
  • InterpolationType.None – A new InterpolationType has been added to the InterpolationType, which does not interpolation but adds data directly and connects the points with triangulation.

The SurfaceType enum has been replaced with three bool properties, which makes the API easier to understand and use.

ScatterFaceSize – the property regulates the size of the polygons that build a 3D scatter. Bigger values lead to bigger polygons, which results in faster performance and more rough scatter mesh.

Effect3D.ShaderEffect – the property can be applied to all 3D chart elements, including scatters and performs much faster.

3D surface chart with color map and wire frame.

3D surface chart with color map and wire frame.

Exporting Images
Two new methods have been added for exporting the chart as an image – CreateImage and ExportImage.

Custom Formatting of Labels in Real-time Charts
A new property has been added to the RealTimeChart library – Axis.LabelFormatProvider. Use it to specify custom formatting of numeric labels. If required, you can specify format arguments for your format classes with Axis.LabelFormat.

MindFusion WebForms DiagrammerMindFusion.Diagramming for WPF

Free-form nodes
A FreeFormNode collects all points from users’ mouse or touch input and displays them as node’s outline. To let users draw free-form nodes interactively, set Diagram.Behavior to DrawFreeForms or LinkFreeforms. Use the Points property of FreeFormNode to get or set outline points programmatically. If the Closed property is set, the node is drawn as a closed shape and its interior filled, or otherwise the node is drawn as a poly-line. If the distance between first and last points drawn by user is shorter than Diagram.AutoCloseDistance, the node’s Closed property is automatically set to true . AutoCloseDistance default value is Double.MaxValue , so free-form nodes are always closed.

Wpf Diagram: Free Shapes

Wpf Diagram: Free Shapes

Shape control points
Shape formulas can now be parameterized by associating control points with Shape objects. Each control point is passed to the shape script as a named variable. Apart from the name, you can specify the default, min and max coordinates for each parameter via the ShapeControlPoint constructor, and whether to treat its values as percents or fixed offset.

Resize table columns and rows
Columns and rows of a TableNode can now be resized interactively if its AllowResizeColumns or AllowResizeRows properties are enabled. In order to resize, move the mouse pointer to the border line on column’s right side or row’s bottom side until it shows resize cursor and start dragging. The control raises TableColumnResizing and TableRowResizing events to let you validate new size or prevent resizing some elements.

Barcode nodes
The BarcodeNode class displays EAN, UPC or QR barcodes as node’s content. In-place edit operations let users enter new numeric codes for 1D codes or text strings for QR codes. The barcode format is specified via the Format property, the encoded number or text is set via Content, and color of 1D bars / 2D modules via BarColor.

Barcode diagram nodes

Barcode diagram nodes

Support for Visio stencils
The diagram can now display shapes from stencil files in Visio 2003 XML stencil format (.vsx). To load a stencil file, use an instance of the VisioStencil class. The shapes are displayed in the diagram through VisioNode objects.

ShapeDesigner improvements

  • The ShapeDesigner control supports undo. Call its Undo or Redo methods to respectively undo or redo a change done to the designed shape.
  • ZoomFactor property added to ShapeDesigner. It also supports interactive zoom in/out via mouse wheel.
  • The SelectedElement property exposes the graphic element currently selected in ShapeDesigner canvas. You can bind to its stroke and brush properties to create alternative user interface for editing element attributes.

AnchorPatern improvements

  • The XUnit and YUnit properties allow specifying the coordinates of an AnchorPoint as a fixed offset from the node’s top-left corner rather than in percentage, so that the point position does not change when the node is resized.
  • The AnchorPattern property of Shape class lets you associate anchor points with shape definitions. If a ShapeNode instance does not contain its own AnchorPattern, it will derive the one defined by the node’s Shape.
  • The RowAnchorPattern property lets you specify default AnchorPattern for all table rows.

Map-16x16MindFusion.Mapping for WPF

Zoom control
The ZoomControl class lets user change interactively the current zoom level and scroll position of a MapView. To set it up, add a ZoomControl to the page, place it anywhere over a MapView, and set the control’s Target property to that view. Set the ZoomStep and ScrollStep properties to specify the amount added to view’s zoom level or scroll position by ZoomControl’s buttons.

map-control-zooming

Miscellaneous

  • The new Behavior property lets users select multiple map elements interactively.

WPF Reporting ToolMindFusion.Reporting for WPF

Report Parameters
Parameters can now be added to a report through the new Parameters collection of the Report class. The parameters provide name, description and value and can be of any type, including expression. For more information about parameters, check the Report Parameters topic.

Barcodes
MindFusion.Reporting for WPF reports can now display UPC-A, UPC-E, EAN-8, EAN-13, and QR barcodes. The barcodes are represented by the new Barcode report item.

wpf_barcode_report_items

Schedule ControlMindFusion.Scheduling for WPF

Interactive Recurrence Rescheduling
Recurrences can be rescheduled interactively by holding down the RescheduleRecurrenceKey while dragging a recurrent item. The control tries to preserve the current pattern of the recurrence when possible.

New Theme
A new built-in theme is available in MindFusion.Scheduling for WPF – the Light theme. It is available through the ThemeType enumeration.

The new 'Light' theme

The new ‘Light’ theme

New Members
Several new properties and events have been added to the control:

You can read details about the new features of the pack at the news page on the forum. The trial version is available for direct download from this link:

Download MindFusion.Pack for WPF 2016.R1

About MindFusion.Wpf Pack: A set of advanced WPF components that help you build your business application easy and on time. The tools provide you with a complete set of features to create, edit and render complex flowcharts, charts, diagrams, calendars, schedules, maps and reports. A set of gauges and UI elements is also included. Each component offers various samples, tutorials and detailed documentation. The controls offer simple and intuitive API, completely customizable appearance, numerous input/output options and a rich event set. Each tool has been thoroughly tested to guarantee that you and your application get the high quality and performance you deserve.

You can read more about the capabilities of each component at its features page:

Prices and licenses are explained in details at the buy page.

MindFusion.WinForms Pack, 2016.R1

MindFusion Pack for WinForms, 2016.R1 has been released. Here is an overview of the new features. You can find details about each new feature here.

Visual Studio 2015 support
MindFusion Pack for WinForms now includes support for Visual Studio 2015. The installer can create VS2015 toolbox palette for the components.

Barcodes
The new BarcodeLabel and BarcodePrinter classes allow displaying and printing EAN, UPC or QR barcodes.

BarcodeLabel:  QR barcodes

BarcodeLabel: QR barcodes

MindFusion WebForms DiagrammerMindFusion.Diagramming

Street maps
MapNodes can render street maps in OpenStreetMap format. Call FromXml method of MapContent to load an .osm file.

MindFusion WinForms  Street maps

MindFusion WinForms Street maps

Resize table columns and rows
Columns and rows of a TableNode can now be resized interactively if its AllowResizeColumns or AllowResizeRows properties are enabled. In order to resize, move the mouse pointer to the border line on column’s right side or row’s bottom side until it shows resize cursor and start dragging.

Barcode nodes
The BarcodeNode class displays EAN, UPC or QR barcodes as node’s content. In-place edit operations let users enter new numeric codes for 1D codes or text strings for QR codes.

Miscellaneous

  • Support for .NET 2 has been dropped; the minimum supported .NET framework version now is 3.5.
  • Distribution now includes a set of digitally-signed assemblies.
  • Undo/redo records for in-place edit operations are now created automatically. They are represented by instances of the EditTextCmd class.
  • CompositeNode supports vertical scrolling in EditComponent (only via keyboard).
  • Support for FromPage and ToPage properties of PrinterSettings .
  • CreateBarcodeNode methods added to the Factory class.
  • The BarcodeNodeStyle property of Diagram defines the default appearance of BarcodeNodes.
  • Improved speed when dragging large hierarchies of grouped nodes.
  • ZoomControl can now be used with other components by MindFusion and has been moved to MindFusion.Common.WinForms assembly and namespace.
  • and much more.

Map-16x16MindFusion.Mapping

Street maps
You can render street maps in OpenStreetMap format by adding a StreetMapLayer instance to the MapView. In order to load a street map, create a new StreetMapLayer > object and call its Map‘s LoadFromXml method to load the corresponding *.osm file.

Zoom control
The ZoomControl class lets user change interactively the current zoom level and scroll position of a MapView. To set it up, add a ZoomControl to the form, place it anywhere over a MapView, and set the control’s Target property to that view.

map-control-zooming

Multiple selection
Now it’s possible to select multiple decorations or map shapes by drawing a selection rectangle. To enable that, set the Behavior property to Select. Selected elements are stored in the Selection collection of respective layer objects.

API changes

  • The type of MapElement‘s Label property has been changed from string to Label class. The FontName and FontSize properties have been moved from MapElement to Label.
  • Type of Layers property changed from List to ObservableCollection .

WPF Reporting ToolMindFusion.Reporting

Barcodes
MindFusion.Reporting reports can now display UPC-A, UPC-E, EAN-8, EAN-13, and QR barcodes. The barcodes are represented by the new Barcode report item.

WinForms Reporter: Barcode Report Items

WinForms Reporter: Barcode Report Items

Miscellaneous

WebForms Scheduler by MindFusionMindFusion.Scheduling

Improved List View
The List view can now display an additional header and a footer. To turn them on, set the appropriate flag to the HeaderStyle property of the ListViewSettings class. The FooterFormat and MainHeaderFormat properties let you customize the text in the respective header. The text can also be customized through the CustomizeText event of the Calendar class. The size of the headers can be specified through the MainHeaderSize and FooterSize properties. Interactive Recurrence Rescheduling Recurrences can be rescheduled interactively by holding down the RescheduleRecurrenceKey while dragging a recurrent item. The control tries to preserve the current pattern of the recurrence when possible.

New Theme
A new built-in theme is available in MindFusion.Scheduling – the Light theme. It is available through the ThemeType enumeration.

The new 'Light' theme

The new ‘Light’ theme

New Properties
Several new properties have been added to the control:

Miscellaneous

Spreadsheet-16x16MindFusion.Spreadsheet

Autofiltering
Worksheets now support autofiltering. To enable it, call the AutoFilter method of the CellRange class. To specify autofiltering criteria for individual columns, use the AutoFilter overload.

WinForms Spreadsheet: Auto filtering

Multiple Selection
MindFusion.Spreadsheet now supports selection of multiple cell ranges. Cell ranges can be added to the selection interactively, by holding down the CTRL key while dragging with the mouse, or programmatically, by using one of the new methods of the Selection class: Add, AddRow, and AddColumn.

Miscellaneous

Installer for the latest version can be downloaded at http://www.mindfusion.eu/WinFormsTrial.zip

Updated assemblies are also available as MindFusion.Pack NuGet package.

About MindFusion.WinForms Pack: A set of five WinForms programming components that provide your application with a rich choice of diagramming, charting, scheduling, mapping, reporting and gauge features. The tools are very easy to implement and use. They boast intuitive API and various step-by-step tutorials to get you started. Both online and offline documentation is available.

A sample browser presents you with all the samples for each control to let you easily navigate to what you need. You can check some of the features of each component right now if you look at the online demos:

Visit the features – page of the components for more information about their capabilities:

You can check the prices and licensing scheme here. All components are royalty-free.

A Monthly Calendar in Java With Events and Recurring Appointments

This is a step-by-step guide that teaches you how to:

  • Setup the MindFusion Scheduler for Java library to display a single
    month calendar.
  • Attach and handle an event when the user clicks a calendar cell.
  • Create and setup recurrent events/appointments.
  • Perform custom drawing on a specific cell.

The sample builds a monthly calendar, which responds to a user click on a calendar cell by creating a recurrent appointment. The appointment is repeated on each subsequent day of the week for unlimited number of months.

When the user selects a given calendar cell (the 6th day of the month), a special icon appears. The icon is rendered using custom drawing.

Note: In this tutorial we use the words “appointment” and “event” interchangeably. Let’s start:

1. How to Setup the Calendar

All packages of the calendar are included in a single *.jar file – JPlanner.jar In our sample we will reference the following packages:

import com.mindfusion.common.*;
import com.mindfusion.common.Rectangle;
import com.mindfusion.drawing.*;
import com.mindfusion.drawing.awt.AwtImage;
import com.mindfusion.scheduling.*;
import com.mindfusion.scheduling.awt.*;
import com.mindfusion.scheduling.model.*;

For detailed reference about the packages and the classes of the schedule library check the online help.

Here are the first settings for our schedule:

  calendar = new AwtCalendar();
  calendar.beginInit();
  //set the current time
  calendar.setCurrentTime(DateTime.now());
  DateTime today = DateTime.today();
  //set the current date
  calendar.setDate(today);
  // Select the current date
  calendar.getSelection().set(DateTime.today());

We create a new calendar and signal that initialization starts. The time and date shown at the application start are the current date and time. We also select the cell with the current date.

Let’s make the calendar show exactly one month:

calendar.setCurrentView(CalendarView.SingleMonth);

By default each cell in a single month view has its header size set to 0, which makes the current date show in the center of the cell. As a consequence any events in the cell won’t have space to be rendered.

Java Scheduler: the header takes all the cell's height

Java Scheduler: the header takes all the cell’s height

Since we plan to create appointments on user click, we must push the header to the top and free cell space for drawing the events. This is very easy to do, just set:

calendar.getMonthSettings().getDaySettings().setHeaderSize(20);

Now the header is 20 px. and the rest will be for our appointments.

Java Scheduler: the header is 20px.

Java Scheduler: the header is 20px.

For now we are ready initializing the calendar.

calendar.endInit();

2. Handling User Clicks.

User clicks are handled with the dateClick event. We need an instance of the CalendarAdapter and there we associate the dateClick event with a method – onDateClicked. The event is fired when a date is selected.

 calendar.addCalendarListener(new CalendarAdapter(){
            public void dateClick(ResourceDateEvent e) {
                onDateClicked(e);
            }

        });

3. Create an Appointment and a Recurrence.

The first part of our event handler method is:

protected void onDateClicked(ResourceDateEvent e) {

    int dayIndex = e.getDate().getDayOfWeek();

    Appointment item = new Appointment();
    item.setStartTime(e.getDate());
    item.setEndTime(e.getDate());
    item.setHeaderText(events[dayIndex]);
    item.getStyle().setBrush(brushes[dayIndex]);

Here we create an Appointment and set its start and end date to the date which was clicked. The ResourceDateEvent keeps data about the date, the resource, if any and other useful information. The header text is the text, which will be rendered at the appointment. The style object contains appearance data for the cell and we use the setBrush
method to change the background of the appointment.

The second part of the method creates the Recurrence object:

      recurrence = new Recurrence();
      recurrence.setPattern(RecurrencePattern.Weekly);
      recurrence.setDaysOfWeek(getDayOfWeek(dayIndex));
      recurrence.setStartDate(e.getDate());
      recurrence.setRecurrenceEnd(RecurrenceEnd.Never);
      item.setRecurrence(recurrence);

The recurrence is once a week. There’s additional work to be done when we set the day of the week with setDaysOfWeek. The method accepts as an argument one of the DaysOfWeek enumeration values and we have to convert the index of the day to such value.

private int getDayOfWeek ( int i ) {

        switch (i) {
            case 1:
                return DaysOfWeek.Monday;
            case 2:
                return DaysOfWeek.Tuesday;
            case 3:
                return DaysOfWeek.Wednesday;
            case 4:
                return DaysOfWeek.Thursday;
            case 5:
                return DaysOfWeek.Friday;
            case 6:
                return DaysOfWeek.Saturday;
        }

        return DaysOfWeek.Sunday;

    }

Finally, let’s add the item with the recurrence pattern to the schedule items collection:

 calendar.getSchedule().getItems().add(item);

4. Custom Drawing a Cell’s Header

The last thing that needs to be done is to draw the icon on the special 6th day of each month. We will perform item drawing and we add to the calendar initialization code this line:

 calendar.setCustomDraw(CustomDrawElements.CalendarItem);

Now we are ready to handle the draw event:

   //add a listener for custom draw
       calendar.addCalendarListener(new CalendarAdapter()
        {
            @Override()
            public void draw(DrawEvent e) {
                onDraw(e);
            }
        });

Below is the first part of the handler method:

 private void onDraw(DrawEvent e)
    {
 if(e.getDate().getDay() == 6 )
            {
                java.awt.Image img = null;

                try {
                    // Read the image file from an input stream
                    InputStream is = new BufferedInputStream(
                            new FileInputStream("../cake.png"));
                    img = ImageIO.read(is);

                } catch (IOException ioe) {
                }

Here we read an image from an InputStream. The calendar method for drawing images requires mindfusion.scheduling.AwtImage and we must convert the java image:

AwtImage awtImage = new AwtImage(img);

Then we get the bounds of the drawing area and render the image:

   //gets the bounds of the drawing area
    Rectangle r = e.getBounds();
             
   //draw the image
   e.getGraphics().drawImage(awtImage, e.getBounds().getLeft(), e.getBounds().getTop(), 32, 32);

 }

The image is 32 x 32 pixels and gets clipped in the appointment.

Java Scheduler: the appointment's height is not enough.

Java Scheduler: the appointment’s height is not enough.

We’ll have to resize the item header to give it more space:

calendar.getItemSettings().setSize(32);

And now everything works just fine:

MindFusion Java Calendar: Month View with Events

MindFusion Java Calendar: Month View with Events

The sample is available for download from here:

Monthly Calendar in Java with Recurrent Appointments and Events

About Scheduling for Java Swing: A programming class library written entirely in Java that lets you build the most sophisticated schedules, calendars and task managers fast and easy. The component boasts a comprehensive feature set that includes custom-typed events, undo/redo functionality, scrolling, tool tips and much more. You can choose among six view styles, which are easy to change and customize. The appearance of each schedule is completely customizable and supports themes, user-assigned mouse cursors and a variety of font, pen and brush options.

A detailed list with the features of the tool is available at the Scheduling for Java Swing features page. The trial version includes a variety of samples and you have plenty of sample code to study. Online documentation with useful tutorials is also available.

The library is royalty-free, source-code is also available. You can see a list of the current prices here. Check the discount page for a list of the available discounts.

Reporting for Silverlight V1.4 and Scheduling for Silverlight, V3.4

MindFusion has released new versions for two of its Silverlight controls – Scheduler and Reporter. Below are details about the new features:

WebForms Scheduler by MindFusionWhat’s New in Scheduler for Silverlight, Version 3.4

Interactive Recurrence Rescheduling
Recurrences can be rescheduled interactively by holding down the RescheduleRecurrenceKey while dragging a recurrent item. The control tries to preserve the current pattern of the recurrence when possible. Otherwise, the recurrence may be modified to accommodate to the new start and end times of the modified item. Interactive rescheduling is not registered in the undo history.

New Theme
A new built-in theme is available in the Silverlight Scheduling control – the Light theme. It is available through the ThemeType enumeration.

Silverlight Scheduler: The Light Theme

Silverlight Scheduler: The Light Theme

New Members

Several new properties and events have been added to the control:

The trial version of Silverlight Scheduler is available for direct download from here:

MindFusion Scheduling for Silverlight, V3.4 Trial Download

The component is also available on Nuget. To install the component, run the following command in the Package Manager Console

PM> Install-Package MindFusion.Scheduling.Silverlight

WPF Reporting ToolWhat’s New in Silverlight Reporter, V1.4

Report Parameters

Parameters can now be added to a report through the new Parameters collection of the Report class. The parameters provide name, description and value and can be of any type, including expression. For more information about parameters, check the Report Parameters topic.

Barcodes

MindFusion Silverlight reports can now display UPC-A, UPC-E, EAN-8, EAN-13, and QR barcodes. The barcodes are represented by the new Barcode report item.

Silverlight Reporter: Barcode Report Items

Silverlight Reporter: Barcode Report Items

Miscellaneous

  • Report items can be searched by name through the new FindItem method.
  • Fixed an issue with horizontal data ranges.
  • Items in data range headers and footers can now bind to the data source of the data range.
  • New sample illustrating the Barcode report items.

You can download the trial version directly from here:

Reporting for Silverlight, V1.4 Trial Download

The component is also available on Nuget. To install the component, run the following command in the Package Manager Console:

PM> Install-Package MindFusion.Reporting.Silverlight

Technical support is available on the MindFusion discussion board, per email at support@mindfusion.eu. or at the Help Desk. Your questions and comments are always welcomed by MindFusion friendly and competent support team.

About MindFusion Scheduler for Silverlight: MindFusion.Scheduling for Silverlight provides your web application with a host of useful features for creating, customizing, importing and exporting calendars, time tables, appointment schedules. What’s more, the component includes a full-features Gantt chart with an activity chart and a resource chart. Unleash your creativity with the vast set of appearance options and enjoy the freedom to create calendars where every single detail is customizable and can be controlled by you. Implement professional Gantt diagrams and bring project planning features to your web software with a few mouse clicks. The library is packed with many samples, tutorials and extensive documentation to help you started. The licensing scheme is very attractive with various discount options and great savings for multiple licenses as well for small companies – check it here.

About Reporting for Silverlight: An intuitive programming component that integrates into any Silverlight application with ease and provides the full range of reporting features needed to render, customize and save business reports. The control ships with a versatile report viewer, optimized to display quickly even the largest reports and packed with a single-button import/export functionality to PDF, Excel as well full-featured print and print preview options. Impress the end-user with elegant charts and unlimited number of pictures. MindFusion reports can host any Silverlight component so you can efficiently change your reports as the requirements of the end user evolve. More on MindFusion Silverlight Reporter here.

Scheduling for WPF, V 3.4 and Reporting for WPF, V1.4

We are pleased to announce new versions for two of MindFusion’s WPF components – Reporting and Scheduling. Below we list the new features and improvements in each of the controls.

WebForms Scheduler by MindFusionNew in Scheduling for WPF, V3.4

Interactive Recurrence Rescheduling
Recurrences can be rescheduled interactively by holding down the RescheduleRecurrenceKey while dragging a recurrent item. The control tries to preserve the current pattern of the recurrence when possible. Otherwise, you can modify the recurrence to accommodate to the new start and end times of the modified item. Interactive rescheduling is not registered in the undo history.

New Theme
A new built-in theme is available in the Scheduler control – the Light theme. It is available through the ThemeType enumeration.

Scheduler for WPF: The Light Theme

Scheduler for WPF: The Light Theme

New API Members
Several new properties and events have been added to the control:

You can download the trial version of the control directly from this link:

Scheduling for WPF, V3.4 Trial Version Download

The component is also available on Nuget. To install the component, run the following command in the Package Manager Console:

PM> Install-Package MindFusion.Scheduling.Wpf

WPF Reporting ToolNew in Reporting for WPF, V1.4

Report Parameters
Parameters can now be added to a report through the new Parameters collection of the Report class. The parameters provide name, description and value and can be of any type, including expression. For more information about parameters, check the Report Parameters topic.

Barcodes
MindFusion WPF Reporter can now display UPC-A, UPC-E, EAN-8, EAN-13, and QR barcodes. The barcodes are represented by the new Barcode report item.

WPF Reporter: Barcode Report Items

WPF Reporter: Barcode Report Items

Improved charts
Several new properties have been added to the LineChart class to imporive the customization for the plot, grid, legend and axes. The axes settings can be specified through the new XAxisSettings and YAxisSettings properties. The AxesChart class exposes four new properties, which can be used to specify the intervals displayed by the chart axes. The new properties are XMinValue, XMaxValue, YMinValue, and YMaxValue.

Miscellaneous

  • Report items can be searched by name through the new FindItem method.
  • Fixed an issue with horizontal data ranges.
  • Items in data range headers and footers can now bind to the data source of the data range.
  • New sample illustrating the Barcode report items.

You can download the trial version of the control directly from this link:

Reportingfor WPF, V1.4 Trial Version Download

The component is also available on Nuget. To install the component, run the following command in the Package Manager Console:

PM> Install-Package MindFusion.Reporting.Wpf

Technical support: You can write at the Scheduling for WPF discussion board and Reporting for WPF discussion board. Additionally, you can write us at support@mindfusion.eu. Anyway we’ll be glad to answer your questions, comments and recommendations and assist you on how to use the MindFusion WPF controls.

About Scheduling for WPF: The perfect programming tool to enhance your WPF application with a compelling set of ready-to-use calendar features. Choose among six types of schedule views all optimized for high performance and easy customization. Treat your users to the convenience of creating appointments with reminders and recurrence options on the fly with the built-in forms. Change every single calendar element to achieve the perfect look without compromise – apply styling, customize the fonts and colors or simply set one of the elegant predefined themes. Persisting the calendar into a variety of formats is easily done with the integrated exporters and importers. The control is also packed with a rich event set that gives you full control over the user’s actions. More about Scheduler for WPF here.

About Reporting for WPF: A programming tool that provides developers with everything they’ll need to create high-impact data driven reports using WPF. The control supports comprehensive list of report elements, which can be nested, combined and customized to create reports optimized for the needs of your current WPF application. A full-featured chart component is integrated into the report tool and you can extend every single report with a compelling chart of your choice. The report can be saved into a variety of formats and rendered on the screen with the built-in elegant viewer for optimal performance. Further details about MindFusion WPF Reporter here.