想实现一个排序的JTable,功能已经实现。现在想实现在点击列字段排序后,在该字段后面画出一个三角形。
Graphics g = getTableHeader().getGraphics();
g.fillPolygon(new int[]{signX -10,signX -15,signX -5}, new int[]{5,15,15}, 3);
g.dispose();
可是三角形一闪而逝,请问如何让三角形显示出来呢?
Graphics g = getTableHeader().getGraphics();
g.fillPolygon(new int[]{signX -10,signX -15,signX -5}, new int[]{5,15,15}, 3);
g.dispose();
可是三角形一闪而逝,请问如何让三角形显示出来呢?
解决方案 »
- 使用SSLSocket发送接收utf-8编码的汉字为什么是乱码??
- 请高手帮忙看看是什么问题
- 菜鸟问题:一个Frame点击一按钮,怎么调用出另一个Frame
- 如何去掉List中的重复元素?
- 求救:关于连接sqlserver数据库中文数据显示为?的问题,我都要崩溃了
- java实现生产者-消费者
- JAVA环境变量设置问题~~win2000下
- 这是什么错误
- 大家来看看这篇文章,有做市场的必看,题材大大的丰富。
- 各位哪儿有Personl web service. 100分重谢!
- A question about displaying image in JTable cell
- Java里如何动态生成方法名!!!
我还想实现我这个功能如果用setAutoCreateRowSorter(true)的话,而我重写了getTableCellRendererComponent()将其中的一列用JCheckBox显示,也重写了getTableCellEditorComponent()方法了。现在一点击这个JCheckBox就报错:Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Invalid range
at javax.swing.DefaultRowSorter.rowsUpdated(DefaultRowSorter.java:879)
at javax.swing.DefaultRowSorter.rowsUpdated(DefaultRowSorter.java:898)
at javax.swing.JTable.notifySorter(JTable.java:4201)
at javax.swing.JTable.sortedTableChanged(JTable.java:4055)
at javax.swing.JTable.tableChanged(JTable.java:4332)
at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:280)
at javax.swing.table.AbstractTableModel.fireTableCellUpdated(AbstractTableModel.java:259)
at javax.swing.table.DefaultTableModel.setValueAt(DefaultTableModel.java:650)
at javax.swing.JTable.setValueAt(JTable.java:2662)
at javax.swing.JTable.editingStopped(JTable.java:4661)
at javax.swing.AbstractCellEditor.fireEditingStopped(AbstractCellEditor.java:125)
at javax.swing.DefaultCellEditor$EditorDelegate.stopCellEditing(DefaultCellEditor.java:330)
at javax.swing.DefaultCellEditor.stopCellEditing(DefaultCellEditor.java:215)
at javax.swing.DefaultCellEditor$EditorDelegate.actionPerformed(DefaultCellEditor.java:347)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.JToggleButton$ToggleButtonModel.setPressed(JToggleButton.java:291)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6038)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
at java.awt.Component.processEvent(Component.java:5803)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4410)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4240)
at javax.swing.plaf.basic.BasicTableUI$Handler.repostEvent(BasicTableUI.java:924)
at javax.swing.plaf.basic.BasicTableUI$Handler.mouseReleased(BasicTableUI.java:1138)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:273)
at java.awt.Component.processMouseEvent(Component.java:6038)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
at java.awt.Component.processEvent(Component.java:5803)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4410)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
at java.awt.Container.dispatchEventImpl(Container.java:2102)
at java.awt.Window.dispatchEventImpl(Window.java:2429)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
没看明白这个错误出在哪?
粘代码了:public class AdvancedJTable extends JTable{
private boolean allowColumnDrag = true;
private boolean autoResize = true;
private boolean allowOrder = true;
private int selectedColumn = -1;
private Vector<Vector> rowData = new Vector<Vector>();
private Vector columnData = new Vector();
private Map<String,Integer> map = new HashMap<String,Integer>();
private void init(){
// this.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
// this.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
// this.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
this.setAllowColumnDrag(this.allowColumnDrag);
this.setAutoResize(this.autoResize);
this.setAllowOrder(this.allowOrder);
// this.getTableHeader().setBackground(new Color(220,180,180));
/*for(int i=0;i<this.getColumnCount();i++){
columnData.add(this.getColumnName(i));
}*/
for(int j=0;j<this.getRowCount();j++){
Vector v = new Vector();
for(int i=0;i<this.getColumnCount();i++){
// System.out.println(i+"\t"+j);
v.add(this.getValueAt(j, i));
}
rowData.add(v);
}
for(int i=0;i<this.getColumnCount();i++){
map.put(this.getColumnModel().getColumn(i).getIdentifier().toString(), 0);
}
}
/*public AdvancedJTable(){
super();
this.init();
}*/
/*public AdvancedJTable(boolean allowColumnDrag,boolean autoResize,boolean allowOrder){
super();
this.allowColumnDrag = allowColumnDrag;
this.autoResize = autoResize;
this.allowOrder = allowOrder;
this.init();
}*/
/*public AdvancedJTable(int numRows,int numColumns){
super(numRows,numColumns);
this.init();
}*/
public AdvancedJTable(Object[][] rowData,Object[] columns){
super(rowData,columns);
this.init();
}
public AdvancedJTable(Object[][] rowData,Object[] columns,boolean allowColumnDrag,boolean autoResize,boolean allowOrder){
super(rowData,columns);
this.allowColumnDrag = allowColumnDrag;
this.autoResize = autoResize;
this.allowOrder = allowOrder;
this.init();
}
/*public AdvancedJTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm){
super(dm,cm,sm);
this.init();
}*/
public AdvancedJTable(Vector rowData,Vector columnData){
super(rowData,columnData);
this.init();
}
public AdvancedJTable(TableModel dm){
super(dm);
this.init();
}
public AdvancedJTable(TableModel dm,boolean allowColumnDrag,boolean autoResize,boolean allowOrder){
super(dm);
this.allowColumnDrag = allowColumnDrag;
this.autoResize = autoResize;
this.allowOrder = allowOrder;
this.init();
}
/*public AdvancedJTable(TableModel dm,TableColumnModel cm){
super(dm,cm);
}*/
public AdvancedJTable(Vector rowData,Vector columnData,boolean allowColumnDrag,boolean autoResize,boolean allowOrder){
super(rowData,columnData);
this.allowColumnDrag = allowColumnDrag;
this.autoResize = autoResize;
this.allowOrder = allowOrder;
this.init();
}
@Override
public void addColumn(TableColumn t){//由於要根據列名來進行排序,因此在addColumn()時要把該columnName加入到map中
// throw new IllegalStateException("addColumn() is not allowed for AdvancedJTable,commented by Hiway@2011-04-07");
//注意 addColumn()方法在構造JTable時就被隱含調用到。而且addColumn()調用時會把所有的column都加進去
// 因此首先clear(),然後手動把所有列加進去,下面的map也一樣
super.addColumn(t);
if(this.columnData!=null){//
this.columnData.clear();
// System.out.println("執行addColumn");
for(int i=0;i<this.getColumnCount();i++){
this.columnData.add(this.getColumnModel().getColumn(i).getHeaderValue());
}
}
if(this.map!=null){
this.map.clear();
// System.out.println("執行put");
for(int i=0;i<this.getColumnCount();i++){
this.map.put(this.getColumnModel().getColumn(i).getHeaderValue().toString(), 0);
}
}
}
@Override
public void updateUI(){
super.updateUI();
this.setAutoResize(true);
System.out.println("updateUI");
}
public void setAllowColumnDrag(boolean flag){
JTableHeader header = this.getTableHeader();
header.setReorderingAllowed(flag);
}
public void setAutoResize(boolean flag){
if(flag){
int totalWidth = 0;
Vector<Integer> vec = new Vector<Integer>();
JTableHeader header = this.getTableHeader();
int rowCount = this.getRowCount();
Enumeration columns = this.getColumnModel().getColumns();
while(columns.hasMoreElements()){
TableColumn column = (TableColumn)columns.nextElement();
int col = header.getColumnModel().getColumnIndex(column.getIdentifier());
int width = (int)this.getTableHeader().getDefaultRenderer().getTableCellRendererComponent(this, column.getIdentifier(), false, false, -1, col).getPreferredSize().getWidth();
for(int i=0;i<rowCount;i++){
int preferedWidth = (int)this.getCellRenderer(i, col).getTableCellRendererComponent(this, this.getValueAt(i, col), false, false, i, col).getPreferredSize().getWidth();
width = Math.max(width, preferedWidth);
}
header.setResizingColumn(column);
vec.add(width+this.getIntercellSpacing().width);
totalWidth += width+this.getIntercellSpacing().width;
column.setWidth(width+this.getIntercellSpacing().width);
}
// System.out.println(totalWidth+"\t"+this.getPreferredSize().width);
if(totalWidth<this.getPreferredSize().width){
// System.out.println("平均各列寬度");
for(int i=0;i<this.getColumnCount();i++){
TableColumn column = this.getColumnModel().getColumn(i);
header.setResizingColumn(column);
// System.out.println("======="+this.getPreferredSize().width/this.getColumnCount());
column.setWidth(vec.get(i)+(this.getPreferredSize().width-totalWidth)/this.getColumnCount());
}
}
}
}
public void setAllowOrder(boolean flag){
if(flag){
this.getTableHeader().setDefaultRenderer(new DefaultTableCellRenderer(){
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){
JButton jb = new JButton();
jb.setMargin(new Insets(0,0,0,0));
jb.setBorderPainted(true);
jb.setBackground(new Color(230,230,230));
jb.setText(value.toString());
return jb;
}
});
this.getTableHeader().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
this.getTableHeader().addMouseListener(new MouseAdapter(){
@Override
public void mouseClicked(MouseEvent e){
if(e.getClickCount()==2 && getRowCount()>0){
// System.out.println("雙擊排序");
// System.out.println("map:"+map);
if(map.size()==0){
for(int i=0;i<getColumnCount();i++){
map.put(getColumnModel().getColumn(i).getHeaderValue().toString(), 0);
}
}
// System.out.println("map:"+map);
selectedColumn = getColumnModel().getColumnIndexAtX(e.getX());
String columnName = getColumnModel().getColumn(selectedColumn).getIdentifier().toString();
// System.out.println(columnData);
// System.out.println(map);
map.put(columnName, map.get(columnName).intValue()+1);
System.out.println("選中的列:"+selectedColumn);
// System.out.println("map"+map);
List<ArrayList> data = new ArrayList<ArrayList>();
for(int i=0;i<getRowCount();i++){
ArrayList v = new ArrayList();
for(int j=0;j<getColumnCount();j++){
v.add(getValueAt(i,j));
}
data.add(v);
}
// System.out.println("原始表中數據:"+data);
Collections.sort(data,new MyComparator());//第一次點擊升序排列
rowData.removeAllElements();
for(int i=0;i<data.size();i++){
Vector v = new Vector();
for(int j=0;j<data.get(i).size();j++){
v.add(data.get(i).get(j).toString());
}
rowData.add(v);
}
// System.out.println("排序后:"+rowData);
if(columnData.size()==0){
for(int i=0;i<getColumnModel().getColumnCount();i++){
columnData.add(getColumnModel().getColumn(i).getHeaderValue().toString());
}
}
// System.out.println(rowData.size()+"\t"+columnData.size());
for(int i=0;i<rowData.size();i++){
for(int j=0;j<columnData.size();j++){
setValueAt(rowData.get(i).get(j),i,j);
}
}
int signX = 0;
for(int i=0;i<=selectedColumn;i++){
TableColumn column = getColumnModel().getColumn(i);
signX += column.getWidth();
}
Graphics g = getTableHeader().getGraphics();
g.create().fillPolygon(new int[]{signX -10,signX -15,signX -5}, new int[]{5,15,15}, 3);
g.dispose();
repaint();
}
}
});
// this.setAutoCreateRowSorter(true);
}
}
public void setHeaderBgColor(Color color){
this.getTableHeader().setBackground(color);
}
public void setCellEditor(int col,JComponent comp){
}
private class MyComparator implements Comparator{
public int compare(Object o1, Object o2) {
ArrayList v1 = (ArrayList) o1;
ArrayList v2 = (ArrayList) o2;
// System.out.println("v1"+v1+"\tv2"+v2);
if(map.get(getColumnModel().getColumn(selectedColumn).getIdentifier().toString())%2==1){
if(v1.get(selectedColumn).toString().compareTo(v2.get(selectedColumn).toString())>0){
return 1;
}
if(v1.get(selectedColumn).toString().compareTo(v2.get(selectedColumn).toString())<0){
return -1;
}
return 0;
}else{
if(v1.get(selectedColumn).toString().compareTo(v2.get(selectedColumn).toString())>0){
return -1;
}
if(v1.get(selectedColumn).toString().compareTo(v2.get(selectedColumn).toString())<0){
return 1;
}
return 0;
}
}
}
}
代码有点乱,大家只需要关注在 setAllowOrder()中怎么把三角形显示出来就行了,多谢!!!
public static void main(String...args){
JFrame frame = new JFrame("AdvancedJTable");
String[][] rowData = new String[][]{{"5","1","7","4"},{"11","0","9","3"}};
String[] columnData = new String[]{"A","B","C","D"};
// AdvancedJTable table = new AdvancedJTable(rowData,columnData,true,true,true);
DefaultTableModel model = new DefaultTableModel(rowData,columnData);
AdvancedJTable table = new AdvancedJTable(model);
// System.out.println(table.getModel() instanceof DefaultTableModel);
model.insertRow(1, new String[]{"J","13","f",""});
model.addColumn("add1", new String[]{"add2","9","add3"});
model.addColumn("add1", new String[]{"9","add2","add3"});
frame.setContentPane(new JScrollPane(table));
frame.setBounds(new Rectangle(10,10,700,600));
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}测试main