All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.becausetesting.commonswindow.utils.ui.JTableUtils Maven / Gradle / Ivy

package com.github.becausetesting.commonswindow.utils.ui;

/*-
 * #%L
 * commons-window
 * $Id:$
 * $HeadURL:$
 * %%
 * Copyright (C) 2016 Alter Hu
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import java.awt.Component;
import java.awt.Point;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Date;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;

import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.JToggleButton;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

import org.apache.log4j.Logger;

import com.github.becausetesting.commonswindow.RowDataModel;

public class JTableUtils {

	private static Logger log = Logger.getLogger(JTableUtils.class);

	private static JTable table;
	private static final String ALL = "✓ Select All";
	private static final String NONE = "✓ Select None";

	public static JTable createTable(DefaultTableModel rowTableModel) {
		return createTable(rowTableModel);
	}

	public static JTable createTable(RowDataModel rowTableModel) {
		table = new JTable(rowTableModel);
		//// workaround for default rowHeight not DPI scaled
		//// (https://bugs.openjdk.java.net/browse/JDK-8029087)
		int fontHeight = table.getFontMetrics(table.getFont()).getHeight();
		table.setRowHeight(fontHeight + (int) (0.2 * fontHeight + 0.5));
		// invoked to set the fillsViewportHeight property. When this property
		// is true the table uses the entire height of the container,
		// even if the table doesn't have enough rows to use the whole vertical
		// space. This makes it easier to use the table as a drag-and-drop
		// target.
		table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		// table.setCellSelectionEnabled(true);
		// table.setColumnSelectionAllowed(true);
		table.setAutoCreateRowSorter(true);
		table.setFillsViewportHeight(true);
		table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); // horizen

		TableColumn tc = table.getColumnModel().getColumn(0);
		// tc.setCellEditor(table.getDefaultEditor(Boolean.class));
		// tc.setCellRenderer(table.getDefaultRenderer(Boolean.class));
		JToggleButton jCheckBox = new JToggleButton(ALL);
		jCheckBox.addItemListener(new ItemListener() {

			@Override
			public void itemStateChanged(ItemEvent e) {
				// TODO Auto-generated method stub
				boolean state = e.getStateChange() == ItemEvent.SELECTED;
				jCheckBox.setText((state) ? NONE : ALL);
				int rowCount = table.getRowCount();
				if (state && rowCount > 0) {
					table.setRowSelectionInterval(0, rowCount - 1);
				} else {
					table.clearSelection();
				}
				for (int r = 0; r < rowCount; r++) {
					table.setValueAt(state, r, 0);

				}
			}
		});
		tc.setHeaderRenderer(new EditableHeader(jCheckBox));
		table.setDefaultRenderer(Date.class, new SQLDateTypeRenderer());
		table.setDefaultRenderer(Timestamp.class, new SQLTimestampTypeRenderer());

		JPopupMenuUtils.tablePopupMenu(table, rowTableModel);
		log.info("Create table finished.");
		return table;
	}

}

class SQLDateTypeRenderer extends DefaultTableCellRenderer {
	private static final long serialVersionUID = 1L;

	@Override
	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
			int row, int column) {
		// TODO Auto-generated method stub
		super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
		if (value != null) {
			Date date = (Date) value;
			String format = new SimpleDateFormat("yyyy-MM-dd").format(date);
			setText(format);
		}
		return this;
	}
}

class SQLTimestampTypeRenderer extends DefaultTableCellRenderer {
	private static final long serialVersionUID = 1L;

	@Override
	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
			int row, int column) {
		// TODO Auto-generated method stub
		super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
		if (value != null) {
			Timestamp date = (Timestamp) value;
			String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date);
			setText(format);

		}
		return this;
	}
}

/**
 * A TableCellRenderer that selects all or none of a Boolean column.
 * http://stackoverflow.com/questions/7137786/how-can-i-put-a-control-in- the-
 * jtableheader-of-a-jtable
 * 
 * @param targetColumn
 *            the Boolean column to manage
 */
class EditableHeader implements TableCellRenderer {

	private JTable table;
	private JComponent component;
	private MouseEventReposter reporter = null;

	public EditableHeader(JComponent component) {
		this.component = component;
		this.component.setFont(UIManager.getFont("TableHeader.font"));
		this.component.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
		this.component.setBackground(UIManager.getColor("TableHeader.background"));
		this.component.setForeground(UIManager.getColor("TableHeader.foreground"));

	}

	@Override
	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
			int row, int column) {
		// TODO Auto-generated method stub
		if (table != null && this.table != table) {
			this.table = table;
			final JTableHeader header = table.getTableHeader();
			if (header != null) {
				this.component.setForeground(header.getForeground());
				this.component.setBackground(header.getBackground());
				this.component.setFont(header.getFont());
				reporter = new MouseEventReposter(header, column, this.component);
				header.addMouseListener(reporter);
			}
		}
		return this.component;
	}

	static public class MouseEventReposter extends MouseAdapter {

		private Component dispatchComponent;
		private JTableHeader header;
		private int column = -1;
		private Component editor;

		public MouseEventReposter(JTableHeader header, int column, Component editor) {
			this.header = header;
			this.column = column;
			this.editor = editor;

		}

		private void setDispatchComponent(MouseEvent e) {
			int col = header.getTable().columnAtPoint(e.getPoint());
			if (col != column || col == -1)
				return;

			Point p = e.getPoint();
			Point p2 = SwingUtilities.convertPoint(header, p, editor);
			dispatchComponent = SwingUtilities.getDeepestComponentAt(editor, p2.x, p2.y);
		}

		private boolean repostEvent(MouseEvent e) {
			if (dispatchComponent == null) {
				return false;
			}
			MouseEvent e2 = SwingUtilities.convertMouseEvent(header, e, dispatchComponent);
			dispatchComponent.dispatchEvent(e2);
			return true;
		}

		@Override
		public void mousePressed(MouseEvent e) {
			if (header.getResizingColumn() == null) {
				Point p = e.getPoint();

				int col = header.getTable().columnAtPoint(p);
				if (col != column || col == -1)
					return;

				int index = header.getColumnModel().getColumnIndexAtX(p.x);
				if (index == -1)
					return;

				editor.setBounds(header.getHeaderRect(index));
				header.add(editor);
				editor.validate();
				setDispatchComponent(e);
				repostEvent(e);
			}
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			repostEvent(e);
			dispatchComponent = null;
			header.remove(editor);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy