137 |
ilm |
1 |
package org.jopencalendar.ui;
|
|
|
2 |
|
|
|
3 |
import java.awt.Cursor;
|
|
|
4 |
import java.awt.Dimension;
|
|
|
5 |
import java.awt.GridLayout;
|
|
|
6 |
import java.awt.Point;
|
|
|
7 |
import java.awt.event.MouseAdapter;
|
|
|
8 |
import java.awt.event.MouseEvent;
|
|
|
9 |
import java.awt.event.MouseListener;
|
|
|
10 |
import java.awt.event.MouseMotionListener;
|
|
|
11 |
import java.beans.PropertyChangeEvent;
|
|
|
12 |
import java.beans.PropertyChangeListener;
|
|
|
13 |
|
|
|
14 |
import javax.swing.JComponent;
|
|
|
15 |
import javax.swing.JScrollPane;
|
|
|
16 |
import javax.swing.JTable;
|
|
|
17 |
import javax.swing.JViewport;
|
|
|
18 |
import javax.swing.event.ChangeEvent;
|
|
|
19 |
import javax.swing.event.ChangeListener;
|
|
|
20 |
import javax.swing.event.TableModelEvent;
|
|
|
21 |
import javax.swing.event.TableModelListener;
|
|
|
22 |
import javax.swing.table.JTableHeader;
|
|
|
23 |
import javax.swing.table.TableColumn;
|
|
|
24 |
import javax.swing.table.TableColumnModel;
|
|
|
25 |
import javax.swing.table.TableModel;
|
|
|
26 |
|
|
|
27 |
public class FixedColumnTable extends JComponent implements ChangeListener, PropertyChangeListener {
|
|
|
28 |
private JTable main;
|
|
|
29 |
private JTable fixed;
|
|
|
30 |
private JScrollPane scrollPane;
|
|
|
31 |
|
|
|
32 |
/*
|
|
|
33 |
* Specify the number of columns to be fixed and the scroll pane containing the table.
|
|
|
34 |
*/
|
|
|
35 |
public FixedColumnTable(int fixedColumns, TableModel model) {
|
|
|
36 |
main = new JTable(model);
|
|
|
37 |
this.scrollPane = new JScrollPane(main);
|
|
|
38 |
|
|
|
39 |
main.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
|
|
|
40 |
main.setAutoCreateColumnsFromModel(false);
|
|
|
41 |
main.addPropertyChangeListener(this);
|
|
|
42 |
|
|
|
43 |
// Use the existing table to create a new table sharing
|
|
|
44 |
// the DataModel and ListSelectionModel
|
|
|
45 |
fixed = new JTable();
|
|
|
46 |
fixed.setAutoCreateColumnsFromModel(false);
|
|
|
47 |
fixed.setModel(main.getModel());
|
|
|
48 |
fixed.setSelectionModel(main.getSelectionModel());
|
|
|
49 |
fixed.setFocusable(false);
|
|
|
50 |
|
|
|
51 |
// Remove the fixed columns from the main table
|
|
|
52 |
// and add them to the fixed table
|
|
|
53 |
for (int i = 0; i < fixedColumns; i++) {
|
|
|
54 |
TableColumnModel columnModel = main.getColumnModel();
|
|
|
55 |
TableColumn column = columnModel.getColumn(0);
|
|
|
56 |
columnModel.removeColumn(column);
|
|
|
57 |
fixed.getColumnModel().addColumn(column);
|
|
|
58 |
}
|
|
|
59 |
|
|
|
60 |
// Add the fixed table to the scroll pane
|
|
|
61 |
fixed.setPreferredScrollableViewportSize(fixed.getPreferredSize());
|
|
|
62 |
scrollPane.setRowHeaderView(fixed);
|
|
|
63 |
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixed.getTableHeader());
|
|
|
64 |
|
|
|
65 |
// Synchronize scrolling of the row header with the main table
|
|
|
66 |
scrollPane.getRowHeader().addChangeListener(this);
|
|
|
67 |
|
|
|
68 |
fixed.getTableHeader().addMouseListener(new MouseAdapter() {
|
|
|
69 |
TableColumn column;
|
|
|
70 |
int columnWidth;
|
|
|
71 |
int pressedX;
|
|
|
72 |
|
|
|
73 |
public void mousePressed(MouseEvent e) {
|
|
|
74 |
JTableHeader header = (JTableHeader) e.getComponent();
|
|
|
75 |
TableColumnModel tcm = header.getColumnModel();
|
|
|
76 |
int columnIndex = tcm.getColumnIndexAtX(e.getX());
|
|
|
77 |
Cursor cursor = header.getCursor();
|
|
|
78 |
if (columnIndex == tcm.getColumnCount() - 1 && cursor == Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)) {
|
|
|
79 |
column = tcm.getColumn(columnIndex);
|
|
|
80 |
columnWidth = column.getWidth();
|
|
|
81 |
pressedX = e.getX();
|
|
|
82 |
header.addMouseMotionListener(this);
|
|
|
83 |
}
|
|
|
84 |
}
|
|
|
85 |
|
|
|
86 |
public void mouseReleased(MouseEvent e) {
|
|
|
87 |
JTableHeader header = (JTableHeader) e.getComponent();
|
|
|
88 |
header.removeMouseMotionListener(this);
|
|
|
89 |
}
|
|
|
90 |
|
|
|
91 |
public void mouseDragged(MouseEvent e) {
|
|
|
92 |
int width = columnWidth - pressedX + e.getX();
|
|
|
93 |
column.setPreferredWidth(width);
|
|
|
94 |
JTableHeader header = (JTableHeader) e.getComponent();
|
|
|
95 |
JTable table = header.getTable();
|
|
|
96 |
table.setPreferredScrollableViewportSize(table.getPreferredSize());
|
|
|
97 |
JScrollPane scrollPane = (JScrollPane) table.getParent().getParent();
|
|
|
98 |
scrollPane.revalidate();
|
|
|
99 |
}
|
|
|
100 |
});
|
|
|
101 |
this.setLayout(new GridLayout(1, 1));
|
|
|
102 |
this.add(scrollPane);
|
|
|
103 |
|
|
|
104 |
main.getModel().addTableModelListener(new TableModelListener() {
|
|
|
105 |
|
|
|
106 |
@Override
|
|
|
107 |
public void tableChanged(TableModelEvent e) {
|
|
|
108 |
// Reload column names
|
|
|
109 |
final TableColumnModel columnModel = main.getColumnModel();
|
|
|
110 |
final int size = columnModel.getColumnCount();
|
|
|
111 |
for (int i = 0; i < size; i++) {
|
|
|
112 |
columnModel.getColumn(i).setHeaderValue(main.getModel().getColumnName(i + 1));
|
|
|
113 |
}
|
|
|
114 |
main.getTableHeader().repaint();
|
|
|
115 |
}
|
|
|
116 |
});
|
|
|
117 |
|
|
|
118 |
}
|
|
|
119 |
|
|
|
120 |
public void stateChanged(ChangeEvent e) {
|
|
|
121 |
// Sync the scroll pane scrollbar with the row header
|
|
|
122 |
JViewport viewport = (JViewport) e.getSource();
|
|
|
123 |
scrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y);
|
|
|
124 |
}
|
|
|
125 |
|
|
|
126 |
public void propertyChange(PropertyChangeEvent e) {
|
|
|
127 |
// Keep the fixed table in sync with the main table
|
|
|
128 |
if ("selectionModel".equals(e.getPropertyName())) {
|
|
|
129 |
fixed.setSelectionModel(main.getSelectionModel());
|
|
|
130 |
}
|
|
|
131 |
if ("model".equals(e.getPropertyName())) {
|
|
|
132 |
fixed.setModel(main.getModel());
|
|
|
133 |
}
|
|
|
134 |
}
|
|
|
135 |
|
|
|
136 |
public void setRowHeight(int height) {
|
|
|
137 |
this.fixed.setRowHeight(height);
|
|
|
138 |
this.main.setRowHeight(height);
|
|
|
139 |
}
|
|
|
140 |
|
|
|
141 |
public void setShowHorizontalLines(boolean showGrid) {
|
|
|
142 |
this.fixed.setShowHorizontalLines(showGrid);
|
|
|
143 |
this.main.setShowHorizontalLines(showGrid);
|
|
|
144 |
}
|
|
|
145 |
|
|
|
146 |
public void setShowGrid(boolean showGrid) {
|
|
|
147 |
this.fixed.setShowGrid(showGrid);
|
|
|
148 |
this.main.setShowGrid(showGrid);
|
|
|
149 |
}
|
|
|
150 |
|
|
|
151 |
public void setColumnWidth(int index, int width) {
|
|
|
152 |
getColumn(index).setWidth(width);
|
|
|
153 |
if (index == 0) {
|
|
|
154 |
final Dimension preferredSize = fixed.getPreferredSize();
|
|
|
155 |
preferredSize.setSize(width, preferredSize.getHeight());
|
|
|
156 |
fixed.setPreferredScrollableViewportSize(preferredSize);
|
|
|
157 |
JScrollPane scrollPane = (JScrollPane) fixed.getParent().getParent();
|
|
|
158 |
scrollPane.revalidate();
|
|
|
159 |
}
|
|
|
160 |
}
|
|
|
161 |
|
|
|
162 |
public void setColumnMinWidth(int index, int width) {
|
|
|
163 |
getColumn(index).setMinWidth(width);
|
|
|
164 |
}
|
|
|
165 |
|
|
|
166 |
public void setColumnMaxWidth(int index, int width) {
|
|
|
167 |
getColumn(index).setMaxWidth(width);
|
|
|
168 |
}
|
|
|
169 |
|
|
|
170 |
public TableColumn getColumn(int index) {
|
|
|
171 |
final int columnCount = fixed.getColumnCount();
|
|
|
172 |
if (index < columnCount) {
|
|
|
173 |
return this.fixed.getColumnModel().getColumn(index);
|
|
|
174 |
} else {
|
|
|
175 |
return this.main.getColumnModel().getColumn(index - columnCount);
|
|
|
176 |
}
|
|
|
177 |
|
|
|
178 |
}
|
|
|
179 |
|
|
|
180 |
@Override
|
|
|
181 |
public synchronized void addMouseListener(MouseListener l) {
|
|
|
182 |
this.fixed.addMouseListener(l);
|
|
|
183 |
this.main.addMouseListener(l);
|
|
|
184 |
}
|
|
|
185 |
|
|
|
186 |
@Override
|
|
|
187 |
public synchronized void addMouseMotionListener(MouseMotionListener l) {
|
|
|
188 |
this.fixed.addMouseMotionListener(l);
|
|
|
189 |
this.main.addMouseMotionListener(l);
|
|
|
190 |
}
|
|
|
191 |
|
|
|
192 |
public int getSelectedRow() {
|
|
|
193 |
return this.main.getSelectedRow();
|
|
|
194 |
}
|
|
|
195 |
|
|
|
196 |
public void ensureVisible(int row, int column) {
|
|
|
197 |
main.scrollRectToVisible(main.getCellRect(row, column, true));
|
|
|
198 |
}
|
|
|
199 |
|
|
|
200 |
public int rowAtPoint(Point point) {
|
|
|
201 |
return this.main.rowAtPoint(point);
|
|
|
202 |
}
|
|
|
203 |
|
|
|
204 |
public int columnAtPoint(Point point) {
|
|
|
205 |
return this.main.columnAtPoint(point);
|
|
|
206 |
}
|
|
|
207 |
|
|
|
208 |
public void setToolTipTextOnHeader(String text) {
|
|
|
209 |
this.main.setToolTipText(text);
|
|
|
210 |
}
|
|
|
211 |
|
|
|
212 |
public void setReorderingAllowed(boolean b) {
|
|
|
213 |
main.getTableHeader().setReorderingAllowed(b);
|
|
|
214 |
}
|
|
|
215 |
|
|
|
216 |
}
|