Java Drag and Drop UI Components

Let’s talk about working with some older Java code. We took on the Floreant POS project to provide our clients with a stable platform that doesn’t run in the browser like their previous platform. Our changes for this project included functional changes such as allowing the relocation of tables to simulate the restaurant’s floor layout, and cosmetic changes to modernize the look of the application. Today we will focus on the table relocation functionality since we found it to be quite interesting to do from scratch.

The Approach

By default, Floreant POS displays table buttons in a grid layout in a JPanel. There is no support to move or resize any of the buttons. To implement the change, we wanted to change as little as possible and thus we decided to add to the existing classes, rather than rewriting the Table Selection View.


In the hierarchy of the project, there are Tables which contain some information, and there are TableButtons which are the UI representation of those tables. We added the x-position and y-position attributes to the Table class to persist this information indefinitely. We then added a MouseListener to the TableButton class to keep track of where the button was moved from and a MouseMotionAdapter to keep track of where the button was moved to. Once the button has been moved, the state is saved in the database and the button will always appear at that location.

//get x and y in button class
private volatile int draggedAtX, draggedAtY;
private MouseAdapter mouseListener  = new MouseAdapter(){
	public void mousePressed(MouseEvent e){
		draggedAtX = e.getX();
		draggedAtY = e.getY();
	}
};
private MouseMotionAdapter mouseMotionListener  = new MouseMotionAdapter(){
	public void mouseDragged(MouseEvent e){
		setLocation(e.getX() - draggedAtX + getLocation().x,
				e.getY() - draggedAtY + getLocation().y);
		shopTable.setX(e.getX() - draggedAtX + getLocation().x);
		shopTable.setY(e.getY() - draggedAtY + getLocation().y);
		ShopTableDAO.getInstance().update(shopTable);
	}
};
//set bounds in drag and drop view
buttonsPanel.setLayout(null);
tableButton.setBounds(shopTable.getX(), shopTable.getY(), shopTable.getWidth(), shopTable.getLength());
buttonsPanel.add(tableButton);

The Pros

This was a simple change to implement with massive benefits. The functionality that this adds to the product makes it much more attractive to a potential customer.The time it took to write this code was much shorter than expected for a feature of this magnitude.

The Cons

While we implemented it later, there was initially no way to check if the buttons were out of bounds. If one were to resize the screen, or accidentally move the button off the screen, it would be gone forever. This is because we are storing the absolute value of the button’s location. We could store the relative value to help with different resolution screens, and we have implemented a checker to keep all buttons within bounds. Another possible issue would the updates to the database. We have to change the positional values for each table very often when we are moving the component. Since this will be seldom used, we decided that it wouldn’t cause any problems to have a spike in database updates when the table layout is being adjusted.

Conclusion

This project is written using Swing, a package that comes with Java and implements some basic UI functionality. In order to keep the number of dependencies as low as possible, we opted to write our functions from scratch. We learned about how MouseMotionAdapters work in order to provide the functionality our customers need.