Java swing:Jtable包含许多模型和自定义渲染器
我有一个jtable,我根据模型的值重新着色行,如下所示:
resultTable = new javax.swing.JTable(){ private Border outside = new MatteBorder(1,1,Color.BLACK); private Border inside = new EmptyBorder(0,1); private Border highlight = new CompoundBorder(outside,inside); public Component prepareRenderer(TableCellRenderer renderer,int row,int column) { Component c = super.prepareRenderer(renderer,row,column); JComponent jc = (JComponent) c; // Color row based on a cell value if (!isRowSelected(row)) { c.setBackground(getBackground()); int modelRow = convertRowIndexToModel(row); if (getStatus().equals("status1")) { myFirstTableModel model = (myFirstTableModel ) resultTable.getModel(); if ((model.getObjectAtRow(modelRow).getMsg().getRegNumIn() == 3)) { c.setBackground(new Color(255,244,148));//YELLOW - needs attension } } else if (getStatus().equals("status2")) { mySecondTableModel model = (mySecondTableModel) resultTable.getModel(); if (model.getObjectAtRow(modelRow).getMsg().getTask() == 2) { c.setBackground(new Color(210,245,176));//GREEN - got attension } } } else if (isRowSelected(row)) { jc.setBorder(highlight); c.setBackground(new Color(201,204,196)); } return c; } }; 我根据SwingWorker线程中的var状态设置了不同的模型(myFirstTableModel,mySecondTableModel),并显示“请等待”的模态对话框. final WaitDialog dialog = new WaitDialog(new javax.swing.JFrame(),true); dialog.addWindowListener(new java.awt.event.WindowAdapter() { }); SwingWorker worker = new SwingWorker() { @Override protected Object doInBackground() throws Exception { setStatus("status2"); Refresh(); return 0; } @Override public void done() { dialog.dispose(); } }; worker.execute(); dialog.setVisible(true); 在Refresh()方法中更改模型: if (getMainFrameStatus().equals("status2")) { @Override public void run() { //Update the model here resultTable.setModel(new mySecondTableModel(data)); } }); 但是我认为在等待对话框混淆我的表时会调用prepareRendere.但是还没有应用不同的模型. 显然我明白了 Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: myFirstTableModel cannot be cast to mySecondTableModel at mySecondTableModel model = (mySecondTableModel) resultTable.getModel(); 我可以允许表调用prepareRenderer吗? 解决方法
最好不要将数据(业务)域的详细信息涂抹到视图中.在你的背景下,你可以f.i.实现清洁分离
>定义一个具有状态概念的界面(需要注意,注意……) 像(未编译,只是一个伪代码片段) public interface StatusAware { enum Status { NORMAL,GOT_ATTENTION,NEEDS_ATTENTION,... } public Status getStatus(int modelIndex); } public class MyFirstTableModel extends AbstractTableModel implements StatusAware { public Statuc getStatus(int modelRow) { boolean needsAttention = getObjectAtRow(modelRow).getMsg().getRegNumIn() == 3; return needsAttention ? NEEDS_ATTENTION : NORMAL; } .... } public class MySecondTableModel extends AbstractTableModel implements StatusAware { public Statuc getStatus(int modelRow) { return // the status of the given row } .... } public class MyTable extends JTable { // if you insist on not using JXTable public Component prepareRenderer(...) { Component comp = super(...) if (getModel() instanceof StatusAware { Status status = ((StatusAware) getModel()).getStatus(convertRowIndexToModel(row)); if (NEEDS_ATTENTION == status) { ... } else if (...) { ... } } return comp; } } 编辑 类似于SwingX(咳嗽……没有教程,只有api doc,wiki,snippets,swinglabs-demo): >实现自定义HighlightPredicate:这决定了给定单元格是否应该在视觉上“装饰”.它只有一种实现方法,允许通过ComponentAdapter对数据进行读访问 摘录自ComponentAdapter api doc HighlightPredicate feverWarning = new HighlightPredicate() { int temperatureColumn = 10; public boolean isHighlighted(Component component,ComponentAdapter adapter) { return hasFever(adapter.getValue(temperatureColumn)); } private boolean hasFever(Object value) { if (!value instanceof Number) return false; return ((Number) value).intValue() > 37; } }; Highlighter hl = new ColorHighlighter(feverWarning,Color.RED,null); table.addHighlighter(hl); 编辑2 不直接支持访问不属于模型的数据.虽然它潜伏了一段时间,它似乎永远不足以跳过它:)它有点违反了基本思想:有一个共同的抽象来访问数据而不知道底层组件的类型和模型(荧光笔) / -Predicate和StringValue对于表,列表,树完全相同). 考虑到这一点,您可以通过适配器的目标组件间接获取它: if (adapter.getComponent() instanceof JTable) { JTable table = (JTable) adapter.getComponent(); TableModel model = table.getModel(); if (model instanceof MyModel) { int modelRow = adapter.convertRowIndexToModel(adapter.row); MyObject object = ((MyModel).getRowObjectAt(modelRow)); ... // check the object } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |