更换行时JTable渲染中断

时间:2014-03-12 16:25:32

标签: java swing jtable

该程序是2个同步数组列表,由2个线程修改。第一个线程是一个创建对象的套接字侦听器。第二个是摆动EDT,其中按钮可以将对象从数组1移动到数组2.两个数组都表示为JTable。对象具有View对象,其中包含要呈现的每个表格单元格的Component。有些字段是实时更新的,大多数都没有。

当我添加第一行时,一切正常,然后从表中删除它,它消失了正确添加一个新行,第0列中的字段不会呈现,直到我点击它,所有其他字段呈现正常。实时字段正确呈现。

对象可视化表示类

public class View implements MouseListener
{
    public final List<JTextField> symbols = new ArrayList<>();
    public final List<JTextField> ratios = new ArrayList<>();
    public final kosilkshik.Position source;
    public final JTextField name = new JTextField();
    public final JTextField mkt = new TextFieldNumber(String.valueOf(mktTime), 2);
    public final JTextField p = new TextFieldNumber(String.valueOf(pTime), 2);
    public final JTextField flip = new TextFieldNumber(String.valueOf(flipTime), 2);
    public final JTextField current = new TextFieldNumber(String.valueOf(currentQty), 2);
    public final JTextField qt = new TextFieldNumber(String.valueOf(getQty()), 2);
    public final JTextField buy = new TextFieldNumber(String.valueOf(buyAt), 2);
    public final JTextField sell = new TextFieldNumber(String.valueOf(sellAt), 2);
    public final JTextField avg = new JTextField(String.valueOf(average), 2);
    public final JTextField bid = new JTextField(String.valueOf(average), 2);
    public final JTextField ask = new JTextField(String.valueOf(average), 2);
    public final JCheckBox invert = new JCheckBox();
    public JButton control;
    public JButton control1;
    public JButton control2;
    public JButton control3;
    {
        bid.setEditable(false);
        ask.setEditable(false);
        avg.setEditable(false);
        name.setText(makeName());
        name.setEditable(false);
        name.repaint();
        name.addMouseListener(this);
    }
    View(kosilkshik.Position p)
    {
        source=p;
        for(TwsConnect.Position c:source.contracts)
        {
            symbols.add(new JTextField(c.contract.localSymbol,15));
            ratios.add(new JTextField(String.valueOf(c.getQty()),2));
            symbols.get(symbols.size()-1).setEditable(false);
            ratios.get(symbols.size()-1).setEditable(false);
        }
        invert.addActionListener(source);
        delete.setActionCommand("delete");
        use.setActionCommand("use");
        send.setActionCommand("send");
        start.setActionCommand("start");
        apply.setActionCommand("apply");
        invert.setActionCommand("invert");
    }
    public void SetColor(Color color)
    {
        if(Color.white.equals(color))
        {
            current.setForeground(Color.BLACK);
            qt.setForeground(Color.BLACK);
            sell.setForeground(Color.BLACK);
            buy.setForeground(Color.BLACK);
        }
        else
        {
            current.setForeground(Color.white);
            qt.setForeground(Color.white);
            sell.setForeground(Color.white);
            buy.setForeground(Color.white);
        }
        current.setBackground(color);
        qt.setBackground(color);
        sell.setBackground(color);
        buy.setBackground(color);
    }
    public void Menu()
    {
        System.out.println("Menu");
        if(m==null)
        {
            JPopupMenu menu = new JPopupMenu();
            menu.add(control);
            menu.add(control1);
            menu.add(control2);
            menu.add(control3);
            menu.setLocation(new Point(name.getLocationOnScreen().x,name.getLocationOnScreen().y+20));
            menu.setLayout(new GridLayout(1,0));
            menu.setVisible(true);
            m = menu;
            Kosilshik.m.add(menu);
        }else
        {
            m.setLocation(new Point(name.getLocationOnScreen().x,name.getLocationOnScreen().y+20));
            m.setVisible(true);
        }
        Kosilshik.allow=true;
        //menu.setLocation(null);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        //Menu();
    }

    @Override
    public void mousePressed(MouseEvent e) {
        Menu();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }
}

为了渲染和编辑,我有一个自定义渲染器。

public class Render implements TableCellRenderer
{
static 
{
    font= new Font(Config.config.getFont(), Font.BOLD, Config.config.getFontSize());
}

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) 
{
    return (Component) value;
}

}

我的桌面模型如此

public class PositionTableModel extends AbstractTableModel
{
private final List<kosilkshik.Position> local;
public PositionTableModel(List<kosilkshik.Position> list)
{
    local = list;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) 
{
    return true;
}
@Override
public int getRowCount(){return local.size();}

@Override
public int getColumnCount() {return 12;}

@Override
public Object getValueAt(int rowIndex, int columnIndex) 
{
    kosilkshik.Position pos = local.get(local.size()-rowIndex-1);
    switch (columnIndex) 
    {
        case 0:                
            return pos.view.name;
        case 1:
            return pos.view.qt;
        case 2:
            return pos.view.current;
        case 3:
            return pos.view.buy;
        case 4:
            return pos.view.sell;
        case 5:
            return pos.view.bid;
        case 6:
            return pos.view.avg;
        case 7:
            return pos.view.ask;
        case 8:
            return pos.view.mkt;
        case 9:
            return pos.view.p;
        case 10:
            return pos.view.flip;
        case 11:
            return pos.view.invert;
        default:
            return pos.view.name;
    }
}

}

2 个答案:

答案 0 :(得分:1)

阅读AbstractTableModel API。

每当您更改TableModel中的数据时,TableModel必须调用相应的fireXXX(...),这将告诉表重绘自己。

答案 1 :(得分:0)

问题在于,单击组件后,它会切换到编辑器模式。所以你需要通过调用

来处理编辑器
table.editingStopped(new ChangeEvent(Component)) // the component that was selected 

或其取消的模拟