G
Guest
Gast
Guten Morgen,
folgendes Problem.
Ich möchte in einer Anwendung die ersten beiden Spalten einer JTable fixieren, damit diese immer für den Anwender sichtbar sind. Die Inhalte der Tabelle sollen gefiltert und sortiert werden können. Deshalb fällt für mich die Lösung über zwei JTable aus. Ich habe im Netz eine Erweiterung von JScrollPane gefunden, die eine Fixierung der Spalten möglich macht. Das funktioniert auch soweit.
Mein Problem ist jetzt das sortieren der Daten.
Bei einem Klick auf den Header, werden alle Daten die nicht in den fixierten Spalten stehen sortiert. die beiden fixierten Spalten bleiben aber unverändert. erst wenn ich mit der maus in den bereich der spalten komme, werden diese auch sortiert.
anbei der code des panels. vielleicht findet ja jemand den fehler warum nicht alles gleichzeitig sortiert wird. is wirklich ne menge code. danke schon im voraus wenn sich einer die mühe macht das durchzuschauen.
folgendes Problem.
Ich möchte in einer Anwendung die ersten beiden Spalten einer JTable fixieren, damit diese immer für den Anwender sichtbar sind. Die Inhalte der Tabelle sollen gefiltert und sortiert werden können. Deshalb fällt für mich die Lösung über zwei JTable aus. Ich habe im Netz eine Erweiterung von JScrollPane gefunden, die eine Fixierung der Spalten möglich macht. Das funktioniert auch soweit.
Mein Problem ist jetzt das sortieren der Daten.
Bei einem Klick auf den Header, werden alle Daten die nicht in den fixierten Spalten stehen sortiert. die beiden fixierten Spalten bleiben aber unverändert. erst wenn ich mit der maus in den bereich der spalten komme, werden diese auch sortiert.
anbei der code des panels. vielleicht findet ja jemand den fehler warum nicht alles gleichzeitig sortiert wird. is wirklich ne menge code. danke schon im voraus wenn sich einer die mühe macht das durchzuschauen.
Code:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
/**
* @author kunok2
*
*/
public class ColumnFixScrollPane extends JScrollPane {
private static final Dimension BUTTOM_SIZE = new Dimension(14, 8);
private JTable table;
private int fixedColCount = 0;
private RowHeader rowHeaderComponent;
private RowHeaderTitle rowHeaderTitleComponent;
private TableEventHandler handler;
private EventDispatcher tableDispatcher;
private EventDispatcher headerDispatcher;
private Dimension tableSize;
private Dimension fixedSize;
private Dimension unfixedSize;
private int fixedWidth;
private int maxFixedColCount;
public ColumnFixScrollPane() {
handler = new TableEventHandler();
rowHeaderComponent = new RowHeader();
rowHeaderTitleComponent = new RowHeaderTitle();
setRowHeaderView(rowHeaderComponent);
setCorner(JScrollPane.UPPER_LEFT_CORNER, rowHeaderTitleComponent);
}
public void setRowHeaderView(Component view) {
if (getRowHeader() == null) {
setRowHeader(super.createViewport());
}
getRowHeader().setView(view);
}
protected JViewport createViewport() {
return new TableViewport();
}
public void setViewportView(Component view) {
super.setViewportView(view);
resetTable();
}
private void resetTable() {
if(viewport.getView() != null && (viewport.getView() instanceof JTable)) {
table = (JTable) viewport.getView();
}
if(table != null) {
rowHeaderComponent.setBackground(table.getBackground());
rowHeaderComponent.setForeground(table.getForeground());
removeEventDispatcher(rowHeaderComponent, tableDispatcher);
removeEventDispatcher(rowHeaderTitleComponent, headerDispatcher);
tableDispatcher = new EventDispatcher(table);
headerDispatcher = new EventDispatcher(table.getTableHeader());
addEventDispatcher(rowHeaderComponent, tableDispatcher);
addEventDispatcher(rowHeaderTitleComponent, headerDispatcher);
if(fixedColCount > 0) {
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
}
calSize();
this.table.getModel().removeTableModelListener(handler);
this.table.getModel().addTableModelListener(handler);
this.table.getSelectionModel().removeListSelectionListener(handler);
this.table.getSelectionModel().addListSelectionListener(handler);
this.table.getColumnModel().removeColumnModelListener(handler);
this.table.getColumnModel().addColumnModelListener(handler);
this.table.addPropertyChangeListener(handler);
}
}
private void calSize() {
if(table == null) {
return;
}
Dimension size = getSize();
int oldFixedWidth = fixedWidth;
TableColumnModel cModel = table.getColumnModel();
JTableHeader tableHeader = table.getTableHeader();
//table Size.
if(tableSize == null) {
tableSize = new Dimension();
} else {
tableSize.width = 0;
tableSize.height = 0;
}
fixedWidth = 0;
maxFixedColCount = 0;
for(int i = 0; i < cModel.getColumnCount(); i++) {
TableColumn col = cModel.getColumn(i);
int cwidth = col.getPreferredWidth();
if(i < fixedColCount) {
fixedWidth += cwidth;
}
tableSize.width += cwidth;
if(tableSize.width < size.width) {
maxFixedColCount++;
}
}
for(int i = 0; i < table.getRowCount(); i++) {
tableSize.height += table.getRowHeight(i);
}
//fixed Size.
if(fixedSize == null) {
fixedSize = new Dimension();
} else {
fixedSize.width = 0;
fixedSize.height = 0;
}
fixedSize.width = fixedWidth;
fixedSize.height = tableSize.height;
//unfixed Size.
if(unfixedSize == null) {
unfixedSize = new Dimension();
} else {
unfixedSize.width = 0;
unfixedSize.height = 0;
}
unfixedSize.width = tableSize.width - fixedWidth;
unfixedSize.height = tableSize.height;
//fixedSize가 변하는 것에 따른 가로 스크롤바의 현재 값을 변경해주어야 한다.
try {
int off = fixedWidth - oldFixedWidth;
Point p = getViewport().getViewPosition();
p.x += off;
getViewport().setViewPosition(p);
} catch(Exception e) {}
}
private void reflash() {
rowHeaderComponent.setPreferredSize(fixedSize);
rowHeaderComponent.revalidate();
rowHeaderComponent.repaint();
rowHeaderTitleComponent.revalidate();
rowHeaderTitleComponent.repaint();
revalidate();
repaint();
}
public Dimension getTableSize() {
return tableSize;
}
public Dimension getTableFixedSize() {
return fixedSize;
}
public Dimension getTableUnFixedSize() {
return unfixedSize;
}
public int getFixedWidth() {
return fixedWidth;
}
public int getFixedColCount() {
return fixedColCount;
}
public void setFixedColCount(int i) {
fixedColCount = i;
resetTable();
}
public JTable getTable() {
return table;
}
public void setTable(JTable table) {
setViewportView(table);
}
public RowHeader getRowHeaderComponent() {
return rowHeaderComponent;
}
public RowHeaderTitle getRowHeaderTitleComponent() {
return rowHeaderTitleComponent;
}
class TableEventHandler implements TableModelListener,
ListSelectionListener, TableColumnModelListener, PropertyChangeListener {
public TableEventHandler() {}
public void tableChanged(TableModelEvent e) {
calSize();
reflash();
}
public void valueChanged(ListSelectionEvent e) {
reflash();
}
public void columnAdded(TableColumnModelEvent e) {
calSize();
reflash();
}
public void columnRemoved(TableColumnModelEvent e) {
calSize();
reflash();
}
public void columnMoved(TableColumnModelEvent e) {
calSize();
reflash();
}
public void columnMarginChanged(ChangeEvent e) {
calSize();
reflash();
}
public void columnSelectionChanged(ListSelectionEvent e) {
calSize();
reflash();
}
public void propertyChange(PropertyChangeEvent evt) {
reflash();
}
}
class EventDispatcher implements MouseListener, MouseMotionListener, MouseWheelListener {
private Component target;
public EventDispatcher(Component t) {
target = t;
}
public void mouseClicked(MouseEvent e) {
if(e.getSource() == rowHeaderComponent) {
if(table.getHeight() < e.getPoint().y) {
dispatchEvent(e);
return;
}
}
target.dispatchEvent(e);
}
public void mousePressed(MouseEvent e) {
if(e.getSource() == rowHeaderComponent) {
if(table.getHeight() < e.getPoint().y) {
dispatchEvent(e);
return;
}
}
if(e.getSource() == rowHeaderTitleComponent) {
rowHeaderComponent.editingStopped(null);
rowHeaderTitleComponent.repaint();
}
target.dispatchEvent(e);
}
public void mouseReleased(MouseEvent e) {
if(e.getSource() == rowHeaderComponent) {
if(table.getHeight() < e.getPoint().y) {
dispatchEvent(e);
return;
}
}
target.dispatchEvent(e);
if(e.getSource() == rowHeaderTitleComponent) {
rowHeaderTitleComponent.repaint();
}
}
public void mouseEntered(MouseEvent e) {
if(e.getSource() == rowHeaderComponent) {
if(table.getHeight() < e.getPoint().y) {
dispatchEvent(e);
return;
}
}
target.dispatchEvent(e);
}
public void mouseExited(MouseEvent e) {
if(e.getSource() == rowHeaderComponent) {
if(table.getHeight() < e.getPoint().y) {
dispatchEvent(e);
return;
}
}
target.dispatchEvent(e);
}
public void mouseDragged(MouseEvent e) {
setToolTipText(e);
((Component) e.getSource()).setCursor(target.getCursor());
if(e.getSource() == rowHeaderComponent) {
if(table.getHeight() < e.getPoint().y) {
dispatchEvent(e);
return;
}
}
target.dispatchEvent(e);
}
public void mouseMoved(MouseEvent e) {
setToolTipText(e);
((Component) e.getSource()).setCursor(target.getCursor());
if(e.getSource() == rowHeaderComponent) {
if(table.getHeight() < e.getPoint().y) {
dispatchEvent(e);
return;
}
}
target.dispatchEvent(e);
}
public void mouseWheelMoved(MouseWheelEvent e) {
setToolTipText(e);
((Component) e.getSource()).setCursor(target.getCursor());
if(e.getSource() == rowHeaderComponent) {
if(table.getHeight() < e.getPoint().y) {
dispatchEvent(e);
return;
}
}
target.dispatchEvent(e);
}
private void setToolTipText(MouseEvent e) {
try {
((JComponent) e.getSource()).setToolTipText(null);
Component comp = null;
if(target instanceof JTable) {
int row = table.rowAtPoint(e.getPoint());
int col = table.columnAtPoint(e.getPoint());
if(row == -1 || col == -1) {
return;
}
comp = table.prepareRenderer(table.getCellRenderer(row, col), row, col);
} else if(target instanceof JTableHeader) {
int col = table.columnAtPoint(e.getPoint());
if(col == -1) {
return;
}
TableColumn aColumn = table.getColumnModel().getColumn(col);
comp = aColumn.getHeaderRenderer().getTableCellRendererComponent(table,
aColumn.getHeaderValue(), false, false, -1, col);
}
if(comp instanceof JComponent) {
String toolTip = ((JComponent) comp).getToolTipText();
if(e.getSource() instanceof JComponent) {
((JComponent) e.getSource()).setToolTipText(toolTip);
repaint();
}
}
} catch(Exception ex) {}
}
}
private static void addEventDispatcher(Component comp, EventDispatcher dispatcher) {
comp.addMouseListener(dispatcher);
comp.addMouseMotionListener(dispatcher);
comp.addMouseWheelListener(dispatcher);
}
private static void removeEventDispatcher(Component comp, EventDispatcher dispatcher) {
comp.removeMouseListener(dispatcher);
comp.removeMouseMotionListener(dispatcher);
comp.removeMouseWheelListener(dispatcher);
}
class EditorRemoverKeyListener extends KeyAdapter {
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {
rowHeaderComponent.editingCanceled(null);
}
if(e.getKeyCode() == KeyEvent.VK_ESCAPE || e.getKeyCode() == KeyEvent.VK_UP ||
e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_TAB) {
rowHeaderComponent.editingStopped(null);
}
if(e.getKeyCode() == KeyEvent.VK_UP) {
int selRow = (rowHeaderComponent.editorRow > 0) ? rowHeaderComponent.editorRow - 1 : 0;
table.clearSelection();
table.addRowSelectionInterval(selRow, selRow);
}
if(e.getKeyCode() == KeyEvent.VK_DOWN) {
int selRow = (rowHeaderComponent.editorRow < table.getRowCount() - 1) ? rowHeaderComponent.editorRow + 1 : table.getRowCount() - 1;
table.clearSelection();
table.addRowSelectionInterval(selRow, selRow);
}
}
}
//Row Header
class RowHeader extends JComponent implements CellEditorListener {
private Component editorComponent;
int editorRow;
int editorCol;
private EditorRemoverKeyListener keyListener;
public RowHeader() {
super();
setDoubleBuffered(true);
keyListener = new EditorRemoverKeyListener();
}
public void paint(Graphics g) {
super.paint(g);
if(table == null || fixedColCount == 0) {
return;
}
Color gridColor = table.getGridColor();
Color backColor = table.getBackground();
JTableHeader header = table.getTableHeader();
TableColumnModel cModel = header.getColumnModel();
TableColumn dragColumn = header.getDraggedColumn();
int row = 0;
int col = 0;
for(row = 0; row < table.getRowCount(); row++) {
for(col = 0; col < table.getColumnCount(); col++) {
if(col >= fixedColCount) {
break;
}
Rectangle spaceRec = table.getCellRect(row, col, true);
Rectangle cellRect = table.getCellRect(row, col, false);
TableColumn aColumn = cModel.getColumn(col);
if(aColumn == dragColumn) {
spaceRec.x += header.getDraggedDistance();
cellRect.x += header.getDraggedDistance();
}
// if(col == 0) {
// System.out.println("(" + row + ", " + col + ") - " + table.isEditing() + ", eR: " + table.getEditingRow() + ", eC: " + table.getEditingColumn());
// }
g.setColor(backColor);
g.fillRect(spaceRec.x, spaceRec.y, spaceRec.width, spaceRec.height);
g.setColor(gridColor);
g.drawRect(spaceRec.x - 1, spaceRec.y - 1, spaceRec.width, spaceRec.height);
if(table.isEditing() && table.getEditingRow() == row &&
table.getEditingColumn() == col) {
if(editorComponent == null) {
editorRow = row;
editorCol = col;
editorComponent = table.getEditorComponent();
editorComponent.setBounds(cellRect);
add(editorComponent);
table.getCellEditor().addCellEditorListener(this);
editorComponent.addKeyListener(keyListener);
}
editorComponent.validate();
super.paint(g);
} else {
if(editorComponent != null && row == editorRow && col == editorCol) {
removeEditor(null);
validate();
super.paint(g);
}
TableCellRenderer renderer = table.getCellRenderer(row, col);
Component component = table.prepareRenderer(renderer, row, col);
SwingUtilities.paintComponent(g.create(), component, this, cellRect);
}
}
}
}
public void editingStopped(ChangeEvent e) {
removeEditor(e);
table.editingStopped(e);
validate();
repaint();
}
public void editingCanceled(ChangeEvent e) {
removeEditor(e);
table.editingCanceled(e);
validate();
repaint();
}
private void removeEditor(ChangeEvent e) {
if(editorComponent != null) {
remove(editorComponent);
editorComponent.removeKeyListener(keyListener);
if(table.getCellEditor() != null) {
table.getCellEditor().removeCellEditorListener(this);
}
editorComponent = null;
editorRow = -1;
editorCol = -1;
}
}
}
//Row Header Title (Upper Left Corner)
class RowHeaderTitle extends JPanel {
private JButton preButton;
private JButton postButton;
public RowHeaderTitle() {
super();
setDoubleBuffered(true);
setOpaque(false);
preButton = new JButton("");
postButton = new JButton("");
preButton.setHorizontalAlignment(SwingConstants.CENTER);
postButton.setHorizontalAlignment(preButton.getHorizontalAlignment());
preButton.setHorizontalTextPosition(SwingConstants.CENTER);
postButton.setHorizontalTextPosition(preButton.getHorizontalTextPosition());
preButton.setFocusPainted(false);
postButton.setFocusPainted(preButton.isFocusPainted());
preButton.setMargin(new Insets(0, 0, 0, 0));
postButton.setMargin(preButton.getMargin());
add(preButton);
add(postButton);
preButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setFixedColCount(fixedColCount - 1);
setButton();
}
});
postButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setFixedColCount(fixedColCount + 1);
setButton();
}
});
}
private void setButton() {
if(fixedColCount == 1) {
preButton.setEnabled(false);
} else {
preButton.setEnabled(true);
}
if(fixedColCount < maxFixedColCount) {
postButton.setEnabled(true);
} else {
postButton.setEnabled(false);
}
}
public void paint(Graphics g) {
if(table == null) {
return;
}
Dimension size = getSize();
postButton.setBounds(new Rectangle(size.width - BUTTOM_SIZE.width, size.height - BUTTOM_SIZE.height, BUTTOM_SIZE.width, BUTTOM_SIZE.height));
preButton.setBounds(new Rectangle(size.width - BUTTOM_SIZE.width * 2, size.height - BUTTOM_SIZE.height, BUTTOM_SIZE.width, BUTTOM_SIZE.height));
setButton();
JTableHeader header = table.getTableHeader();
TableColumnModel cModel = header.getColumnModel();
TableColumn dragColumn = header.getDraggedColumn();
for(int i = 0; i < cModel.getColumnCount(); i++) {
if(i >= fixedColCount) {
break;
}
TableColumn aColumn = cModel.getColumn(i);
TableCellRenderer renderer = aColumn.getHeaderRenderer();
if (renderer == null) {
renderer = header.getDefaultRenderer();
}
Component comp = renderer.getTableCellRendererComponent(header.getTable(),
aColumn.getHeaderValue(), false, false, -1, i);
Rectangle rec = header.getHeaderRect(i);
rec.width -= table.getIntercellSpacing().width;
if(aColumn == dragColumn) {
rec.x += header.getDraggedDistance();
}
SwingUtilities.paintComponent(g.create(), comp, this, rec);
}
super.paint(g);
}
}
class TableViewport extends JViewport {
@Override
public Dimension getViewSize() {
return unfixedSize;
}
@Override
public Point getViewPosition() {
Point p = super.getViewPosition();
p.x -= fixedWidth;
return p;
}
@Override
public void setViewPosition(Point p) {
p.x += fixedWidth;
super.setViewPosition(p);
}
}
}