当前位置: 代码迷 >> J2SE >> JScrollPane中JTable更新内容有关问题
  详细解决方案

JScrollPane中JTable更新内容有关问题

热度:45   发布时间:2016-04-24 00:31:20.0
JScrollPane中JTable更新内容问题
我在一个大的panel中用BorderLayout布局,把scrollpane加在east,如下所示

scrollpane初始状态里面是没有表格的,后面有个函数在每次更新表格数据时调用,将表格加进scrollpane

然后界面一生成布局就混乱。。。得把鼠标移来移去才能看到组建出现,还是不完整的出现,后面更新数据也一样。求教。。。

Java code
           private JScrollPane playerScrollPane;           public FieldPanel(){     //panel的构造函数                playerScrollPane=new JScrollPane();        playerScrollPane.setPreferredSize(new Dimension(200, 400));   //大的panel的大小是(800,600)        add(playerScrollPane,BorderLayout.EAST);           }           //.........           public void setPlayersTable(Map<LoginMessage, Integer> playersMap){        Set<LoginMessage> playersSet=playersMap.keySet();        Iterator<LoginMessage> iterator=playersSet.iterator();                final Object [][] data =new Object[playersMap.size()][4];        for(int i=0;i<playersMap.size()&&iterator.hasNext();i++){            LoginMessage loginMessage=iterator.next();            data[i][0]="";//头像            data[i][1]=loginMessage.name;            data[i][2]=loginMessage.rank;            data[i][3]=loginMessage.mark;        }        TableModel tableModel=new AbstractTableModel() {                        @Override            public Object getValueAt(int rowIndex, int columnIndex) {                // TODO Auto-generated method stub                return data[rowIndex][columnIndex];            }                        @Override            public int getRowCount() {                // TODO Auto-generated method stub                return data.length;            }                        @Override            public int getColumnCount() {                // TODO Auto-generated method stub                return 4;            }            public String getColumnName(int column) {return names[column];}                        public Class getColumnClass(int c) {return getValueAt(0, c).getClass();}                        public boolean isCellEditable(int row, int col) {return false;}                        public void setValueAt(Object aValue, int row, int column) { data[row][column] = aValue; }        };            playersTable=new JTable(tableModel);        TableRowSorter<TableModel> rowSorter=new TableRowSorter<TableModel>(tableModel);        playersTable.setRowSorter(rowSorter);        playersTable.setRowHeight(50);                SwingUtilities.invokeLater(new Runnable() {                        @Override            public void run() {                // TODO Auto-generated method stub        关键就在这里面了,数据是更新了,但布局一片混乱                playerScrollPane.setViewportView(playersTable);//                playerScrollPane.validate();//                playerScrollPane.repaint();                repaint();            }        });    }



------解决方案--------------------
其次,不要每次更新数据就建一个新的JTable。
更新你的数据model,然后通知JTable重绘。示例代码如下:

Java code
import java.awt.BorderLayout;import java.awt.Dimension;import java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.Map;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTable;import javax.swing.table.AbstractTableModel;public class FieldPanel extends JPanel {  private JScrollPane playerScrollPane;  private LoginMessageTableModel tableModel;  public FieldPanel() {        setLayout(new BorderLayout());        tableModel = new LoginMessageTableModel();        playerScrollPane = new JScrollPane(new JTable(tableModel));    playerScrollPane.setPreferredSize(new Dimension(200, 400));    add(playerScrollPane, BorderLayout.EAST);  }  public void setPlayersTable(Map<LoginMessage, Integer> playersMap) {        tableModel.setData(playersMap.keySet());  }}class LoginMessage {    Object name, mark, rank;}class LoginMessageTableModel extends AbstractTableModel {    private static enum Col {        Unknown ("Unknown", Object.class) {            @Override      Object getData(LoginMessage message) {                assert message != null;        return "";      }    },    Name ("Name", Object.class) {            @Override      Object getData(LoginMessage message) {                assert message != null;        return message.name;      }    },    Rank ("Rank", Object.class) {            @Override      Object getData(LoginMessage message) {                assert message != null;        return message.rank;      }    },    Mark ("Mark", Object.class) {            @Override      Object getData(LoginMessage message) {                assert message != null;        return message.mark;      }    },    ;        private final String display;    private final Class<?> type;    private Col(String display, Class<?> type) {            this.display = display;      this.type = type;    }        abstract Object getData(LoginMessage message);  }    private static final String[] COL_NAMES = new String[] {        "Unknown", "Name", "Rank", "Mark"  };    private volatile List<LoginMessage> data;  LoginMessageTableModel() {        data = Collections.emptyList();  }    void setData(Iterable<LoginMessage> messages) {        List<LoginMessage> list = new ArrayList<LoginMessage>();    for(LoginMessage message : messages)      list.add(message);        data = list;    fireTableDataChanged();  }  @Override  public int getRowCount() {        return data.size();  }  @Override  public int getColumnCount() {        return Col.values().length;  }  @Override  public String getColumnName(int columnIndex) {        return Col.values()[columnIndex].display;  }  @Override  public Class<?> getColumnClass(int columnIndex) {        return Col.values()[columnIndex].type;  }  @Override  public boolean isCellEditable(int rowIndex, int columnIndex) {        return false;  }  @Override  public Object getValueAt(int rowIndex, int columnIndex) {        LoginMessage message = data.get(rowIndex);    return Col.values()[columnIndex].getData(message);  }  @Override  public void setValueAt(Object aValue, int rowIndex, int columnIndex) {}}
  相关解决方案