Month: November 2012

Java: Auto Adjust JTable Columns

Posted on

Perhaps the most common task to be done by a programmer after creating a JTable is to figure out how to adjust the columns to make it look good. I can not remember how many times I have created applications with many JTables and then came to the point where I needed to adjust the columns. At times you may also want to hide certain columns. This stuff comes out of the box with applications like Excel.

After extensive research and testing code (this was years ago by the way) I have come up with some nice code to adjust the columns of a JTable in a reusable way. Just call the method adjustTableColumns() and give it some parameters. See the code below to see how it works and what parameters to send.

public void adjustTableColumns(JTable table) {
	for(int i=0; i < table.getColumnCount(); i++) {
		adjustColumn(i, 5, table);
	}
}
	
public void adjustTableColumns(JTable table, int ... hiddenColumns) {
	for(int i=0; i < table.getColumnCount(); i++) {
                adjustColumn(i, 5, table, hiddenColumns);
        }
}
	
private void adjustColumn(int columnIndex, int margin, JTable table) {
	int width = 0;
	DefaultTableColumnModel colModel = (DefaultTableColumnModel)table.getColumnModel();
	TableColumn column = colModel.getColumn(columnIndex);

	TableCellRenderer renderer = column.getHeaderRenderer();
	if(renderer == null) {
		renderer = table.getTableHeader().getDefaultRenderer();
	}

	Component component = renderer.getTableCellRendererComponent(table, column.getHeaderValue(), false, false, 0, 0);
	width = component.getPreferredSize().width;

	for(int i=1; i < table.getRowCount(); i++) {
		renderer = table.getCellRenderer(i, columnIndex);
		component = renderer.getTableCellRendererComponent(table, table.getValueAt(i, columnIndex), false, false, i, columnIndex);
		width = Math.max(width, component.getPreferredSize().width);
	}

	width += 2*margin;
	column.setPreferredWidth(width);
}

private void adjustColumn(int columnIndex, int margin, JTable table, int ... hiddenColumns) {
	int width = 0;
	DefaultTableColumnModel colModel = (DefaultTableColumnModel)table.getColumnModel();
	TableColumn column = colModel.getColumn(columnIndex);

	for(int j = 0; j < hiddenColumns.length; j++) {
		if(hiddenColumns[j] == columnIndex) {
			column.setMaxWidth(0);
			column.setMinWidth(0);
			column.setPreferredWidth(0);
			column.setResizable(false);
		}
		else {
			TableCellRenderer renderer = column.getHeaderRenderer();
			if(renderer == null) {
				renderer = table.getTableHeader().getDefaultRenderer();
			}

			Component component = renderer.getTableCellRendererComponent(table, column.getHeaderValue(), false, false, 0, 0);
			width = component.getPreferredSize().width;

			for(int i=1; i < table.getRowCount(); i++) {
				renderer = table.getCellRenderer(i, columnIndex);
				component = renderer.getTableCellRendererComponent(table, table.getValueAt(i, columnIndex), false, false, i, columnIndex);
				width = Math.max(width, component.getPreferredSize().width);
			}

			width += 2*margin;
			column.setPreferredWidth(width);
		}
	}
}

Java: Copy Directory & Recursive Delete

Posted on

There are a few tasks that are not easily done in Java. Two of the ones that I encountered are to recursively copy a directory from one location to another and to recursively delete a directory. Oracle’s Java API provides a function to delete a directory but only when it is empty. A bit a annoying since most operating systems provide you with a command to recursively delete directories, why re-invent the wheel?

public void recursiveDelete(File rootDir) {
	recursiveDelete(rootDir, true);
}

public void recursiveDelete(File rootDir, boolean deleteRoot) {
	File[] childDirs = rootDir.listFiles();
	for(int i = 0; i < childDirs.length; i++) {
		if(childDirs[i].isFile()) {
			childDirs[i].delete();
		}
		else {
			recursiveDelete(childDirs[i], deleteRoot);
			childDirs[i].delete();
		}
	}
		
	if(deleteRoot) {
		rootDir.delete();
	}
}

Copying directories is another issue that is not supported in Java (at least until 1.6.x) It seems Java 7 has some support for this, though I have not tested it. Though you would still want some common code that would run on Java 5, 6, and 7 for backwards compatibility.

public void copyDirectory(File sourceLocation, File targetLocation) throws IOException {
	if(sourceLocation.isDirectory()) {
		if(!targetLocation.exists()) {
			targetLocation.mkdir();
		}

		String[] children = sourceLocation.list();
		for(int i = 0; i < children.length; i++) {
			copyDirectory(new File(sourceLocation, children[i]), new File(targetLocation, children[i]));
		}
	}
	else {
		InputStream in = new FileInputStream(sourceLocation);
		OutputStream out = new FileOutputStream(targetLocation);
		
		try {
			byte[] buf = new byte[1024];
			int len;
			while((len = in.read(buf)) > 0) {
				out.write(buf, 0, len);
			}
		}
		finally {
			in.close();
			out.close();
		}
	}
}

MySQL Replication & Cluster Evaluation

Posted on Updated on

I have recently written a short evaluation of MySQL Replication and Cluster. This was done mainly as a study to evaluate which setup of MySQL Replication or Cluster is better suited to my needs for certain projects.

MySQL Replication

  • Scales the database beyond the single instance capacity constraints
  • Load balance read/write queries
  • Highly Available setup
  • Increase read performance and decrease database load

MySQL replication setups usually consists of a master and slave server. The master server handles reads and writes while slave servers handle only reads. In a situation where SELECT queries dominate over INSERT/UPDATE/DELETE it is ideal to have 1 master handle only writes and many slaves handle all the reads. It is common practice to see a setup of 1 master and 30 slaves.


Read the rest of this entry »