001: /*
002: * TableColumnOptimizer.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.gui.components;
013:
014: import java.awt.Component;
015: import java.awt.Font;
016: import java.awt.FontMetrics;
017: import javax.swing.JLabel;
018: import javax.swing.table.JTableHeader;
019: import javax.swing.table.TableCellRenderer;
020: import javax.swing.table.TableColumn;
021: import javax.swing.table.TableColumnModel;
022: import workbench.gui.renderer.WbRenderer;
023: import workbench.resource.Settings;
024: import workbench.util.StringUtil;
025:
026: /**
027: * A class to adjust the columns of a WbTable to the displayed values.
028: *
029: * @author support@sql-workbench.net
030: */
031: public class TableColumnOptimizer {
032: private WbTable table;
033:
034: public TableColumnOptimizer(WbTable client) {
035: this .table = client;
036: }
037:
038: public void optimizeAllColWidth() {
039: this .optimizeAllColWidth(Settings.getInstance()
040: .getMinColumnWidth(), Settings.getInstance()
041: .getMaxColumnWidth(), Settings.getInstance()
042: .getIncludeHeaderInOptimalWidth());
043: }
044:
045: public void optimizeAllColWidth(boolean respectColName) {
046: this .optimizeAllColWidth(Settings.getInstance()
047: .getMinColumnWidth(), Settings.getInstance()
048: .getMaxColumnWidth(), respectColName);
049: }
050:
051: public void optimizeAllColWidth(int minWidth, int maxWidth,
052: boolean respectColName) {
053: int count = this .table.getColumnCount();
054: for (int i = 0; i < count; i++) {
055: this
056: .optimizeColWidth(i, minWidth, maxWidth,
057: respectColName);
058: }
059: }
060:
061: public void optimizeColWidth(int aColumn) {
062: this .optimizeColWidth(aColumn, 0, -1, false);
063: }
064:
065: public void optimizeColWidth(int aColumn, boolean respectColName) {
066: this .optimizeColWidth(aColumn, Settings.getInstance()
067: .getMinColumnWidth(), Settings.getInstance()
068: .getMaxColumnWidth(), respectColName);
069: }
070:
071: public void optimizeColWidth(int aColumn, int minWidth, int maxWidth) {
072: this .optimizeColWidth(aColumn, minWidth, maxWidth, false);
073: }
074:
075: public void optimizeColWidth(int aColumn, int minWidth,
076: int maxWidth, boolean respectColumnName) {
077: if (aColumn < 0 || aColumn > this .table.getColumnCount() - 1) {
078: return;
079: }
080: TableColumnModel colMod = this .table.getColumnModel();
081: TableColumn col = colMod.getColumn(aColumn);
082: int addWidth = this .getAdditionalColumnSpace();
083: int optWidth = minWidth;
084:
085: if (respectColumnName) {
086: JTableHeader th = this .table.getTableHeader();
087: TableCellRenderer rend = col.getCellRenderer();
088: if (rend == null) {
089: rend = th.getDefaultRenderer();
090: }
091: String colName = table.getColumnName(aColumn);
092: Component c = rend.getTableCellRendererComponent(
093: this .table, colName, false, false, 0, aColumn);
094: Font headerFont = c.getFont();
095: FontMetrics hfm = c.getFontMetrics(headerFont);
096: int headerWidth = hfm.stringWidth(colName) + addWidth + 5;
097: optWidth = Math.max(minWidth, headerWidth);
098: }
099:
100: int rowCount = this .table.getRowCount();
101:
102: String s = null;
103: int stringWidth = 0;
104:
105: for (int row = 0; row < rowCount; row++) {
106: TableCellRenderer rend = this .table.getCellRenderer(row,
107: aColumn);
108: Component c = rend.getTableCellRendererComponent(
109: this .table, table.getValueAt(row, aColumn), false,
110: false, row, aColumn);
111: Font f = c.getFont();
112: FontMetrics fm = c.getFontMetrics(f);
113: if (c instanceof WbRenderer) {
114: s = ((WbRenderer) c).getDisplayValue();
115: } else if (c instanceof JLabel) {
116: // DefaultCellRenderer is a JLabel
117: s = ((JLabel) c).getText();
118: } else {
119: s = this .table.getValueAsString(row, aColumn);
120: }
121:
122: if (s == null || s.length() == 0) {
123: stringWidth = 0;
124: } else {
125: String visible = StringUtil.rtrim(s);
126: stringWidth = fm.stringWidth(visible);
127: if (visible.length() < s.length()) {
128: stringWidth += fm.stringWidth("www");
129: }
130: }
131:
132: optWidth = Math.max(optWidth, stringWidth + addWidth);
133: }
134: if (maxWidth > 0) {
135: optWidth = Math.min(optWidth, maxWidth);
136: }
137: if (optWidth > 0) {
138: col.setPreferredWidth(optWidth);
139: }
140: }
141:
142: private int getAdditionalColumnSpace() {
143: int addWidth = this .table.getIntercellSpacing().width * 2;
144: if (this .table.getShowVerticalLines()) {
145: addWidth += 4;
146: }
147: return addWidth;
148: }
149:
150: /**
151: * Adjusts the columns to the width defined from the
152: * underlying tables (i.e. getColumnWidth() for each column)
153: * This does not adjust the width of the columns to the content.
154: *
155: * @see #optimizeAllColWidth()
156: */
157: public void adjustColumns(boolean adjustToColumnLabel) {
158: if (this .table.getModel() == null) {
159: return;
160: }
161: DataStoreTableModel dwModel = this .table
162: .getDataStoreTableModel();
163: if (dwModel == null) {
164: return;
165: }
166:
167: Font f = this .table.getFont();
168: FontMetrics fm = this .table.getFontMetrics(f);
169: int charWidth = fm.stringWidth("n");
170: TableColumnModel colMod = this .table.getColumnModel();
171: if (colMod == null) {
172: return;
173: }
174:
175: int minWidth = Settings.getInstance().getMinColumnWidth();
176: int maxWidth = Settings.getInstance().getMaxColumnWidth();
177:
178: for (int i = 0; i < colMod.getColumnCount(); i++) {
179: TableColumn col = colMod.getColumn(i);
180: int addWidth = this .getAdditionalColumnSpace();
181: int addHeaderWidth = this .getAdditionalColumnSpace();
182:
183: int lblWidth = 0;
184: if (adjustToColumnLabel) {
185: String s = dwModel.getColumnName(i);
186: lblWidth = fm.stringWidth(s) + addHeaderWidth;
187: }
188: int width = (dwModel.getColumnWidth(i) * charWidth)
189: + addWidth;
190: int w = Math.max(width, lblWidth);
191: if (maxWidth > 0) {
192: w = Math.min(w, maxWidth);
193: }
194: if (minWidth > 0) {
195: w = Math.max(w, minWidth);
196: }
197: col.setPreferredWidth(w);
198: }
199: }
200: }
|