DefualtTableCellRenderer中的JTable中的旧值 [英] Old value in JTable within DefualtTableCellRenderer

查看:62
本文介绍了DefualtTableCellRenderer中的JTable中的旧值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试了数周的时间,以通过使用 RGBtoHSV 更改背景颜色来使 JTable 中的 Cell 闪烁,我是可以使用我发现的在线搜索方法来刷新单行,但是当涉及到多行时,它似乎不起作用.

I've been trying for weeks to get a Cell in a JTable to flash by changing the background color with RGBtoHSV, I am able to flash a single row using a method I found searching online but when it comes to multiple rows it does not seem to work.

我尝试创建自定义渲染器类,但仍然无法找到一种方法,当oldvalue<时,使用旧值和新值来刷新单元格.newvalue.

I've tried creating a custom renderer class but still unable to find a way to have the old value with the new value to flash the cell when oldvalue < newvalue.

我为获取该单元格的 oldValue 的所有尝试均失败了,因此它不在其中.我尝试了 TableCellListener ,这是一个使用googlefu找到的类,但是我不知道如何将其实现到渲染器中,尽管将其成功实现到表中也是如此.

All my attempts on getting the oldValue for the cell has failed so its not in there. I have tried TableCellListener, a class I found using my googlefu but I had no idea how to implement this into a renderer, although implementing it to a table was successful.

DefaultTableCellRenderer cTaxas = new DefaultTableCellRenderer() {

        Color gray = new Color(212, 212, 212);

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                boolean hasFocus, int row, int column) {
            Component cellComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row,
                    column);

            if (table.getValueAt(row, column) != null && !isSelected && (row % 2) == 0) {
                cellComponent.setBackground(gray);
                cellComponent.setForeground(Color.BLACK);
            } else if (table.getValueAt(row, column) != null && !isSelected) {
                cellComponent.setBackground(Color.WHITE);
                cellComponent.setForeground(Color.BLACK);
            }

            return cellComponent;
        }

    };
    cTaxas.setHorizontalAlignment(SwingConstants.CENTER);

我正在尝试实现在搜索时发现的 TableCellListener .class之类的东西,但要在 DefaultCellRenderer 中.

I'm trying to achieve something like the TableCellListener.class I have found while searching, but within the DefaultCellRenderer.

public class TableCellListener implements PropertyChangeListener, Runnable {
private JTable table;
private Action action;

private int row;
private int column;
private Object oldValue;
private Object newValue;

/**
 * Create a TableCellListener.
 *
 * @param table
 *            the table to be monitored for data changes
 * @param action
 *            the Action to invoke when cell data is changed
 */
public TableCellListener(JTable table, Action action) {
    this.table = table;
    this.action = action;
    this.table.addPropertyChangeListener(this);
}

/**
 * Create a TableCellListener with a copy of all the data relevant to the
 * change of data for a given cell.
 *
 * @param row
 *            the row of the changed cell
 * @param column
 *            the column of the changed cell
 * @param oldValue
 *            the old data of the changed cell
 * @param newValue
 *            the new data of the changed cell
 */
private TableCellListener(JTable table, int row, int column, Object oldValue, Object newValue) {
    this.table = table;
    this.row = row;
    this.column = column;
    this.oldValue = oldValue;
    this.newValue = newValue;
}

/**
 * Get the column that was last edited
 *
 * @return the column that was edited
 */
public int getColumn() {
    return column;
}

/**
 * Get the new value in the cell
 *
 * @return the new value in the cell
 */
public Object getNewValue() {
    return newValue;
}

/**
 * Get the old value of the cell
 *
 * @return the old value of the cell
 */
public Object getOldValue() {
    return oldValue;
}

/**
 * Get the row that was last edited
 *
 * @return the row that was edited
 */
public int getRow() {
    return row;
}

/**
 * Get the table of the cell that was changed
 *
 * @return the table of the cell that was changed
 */
public JTable getTable() {
    return table;
}

//
// Implement the PropertyChangeListener interface
//
@Override
public void propertyChange(PropertyChangeEvent e) {
    // A cell has started/stopped editing

    if ("tableCellEditor".equals(e.getPropertyName())) {
        if (table.isEditing())
            processEditingStarted();
        else
            processEditingStopped();
    }
}

/*
 * Save information of the cell about to be edited
 */
private void processEditingStarted() {
    // The invokeLater is necessary because the editing row and editing
    // column of the table have not been set when the "tableCellEditor"
    // PropertyChangeEvent is fired.
    // This results in the "run" method being invoked

    SwingUtilities.invokeLater(this);
}

/*
 * See above.
 */
@Override
public void run() {
    row = table.convertRowIndexToModel(table.getEditingRow());
    column = table.convertColumnIndexToModel(table.getEditingColumn());
    oldValue = table.getModel().getValueAt(row, column);
    newValue = null;
}

/*
 * Update the Cell history when necessary
 */
private void processEditingStopped() {
    newValue = table.getModel().getValueAt(row, column);

    // The data has changed, invoke the supplied Action

    if (!newValue.equals(oldValue)) {
        // Make a copy of the data in case another cell starts editing
        // while processing this change

        TableCellListener tcl = new TableCellListener(getTable(), getRow(), getColumn(), getOldValue(),
                getNewValue());

        ActionEvent event = new ActionEvent(tcl, ActionEvent.ACTION_PERFORMED, "");
        action.actionPerformed(event);
    }
}

}

我像这样在我的JTable中使用了celllistener:

I used the celllistener in my JTable like this:

Action action = new AbstractAction() {
public void actionPerformed(ActionEvent e)
{
    TableCellListener tcl = (TableCellListener)e.getSource();
    System.out.println("Row   : " + tcl.getRow());
    System.out.println("Column: " + tcl.getColumn());
    System.out.println("Old   : " + tcl.getOldValue());
    System.out.println("New   : " + tcl.getNewValue());
}
};
TableCellListener tcl = new TableCellListener(table, action);

我正在尝试让此类在JTables Renderer中工作,以便当旧值小于从数据库中提取的新值时,可以刷新 Cell .

I'm trying to get this class working within a JTables Renderer so I can flash the Cell when the old value is less than the new value that has been pulled from a database.

我希望有人可以阐明如何在渲染器中获得旧值,或使用其他方法刷新单元格表.

I'm hoping someone can shed some light as to how I can get the old value within the renderer or a different method of flashing cell tables.

推荐答案

您似乎有两个要求

  1. 我如何获得旧价值
  2. 但是当涉及到多行时,它似乎不起作用.

不太确定它们之间的关系.您一次只能在编辑器中更改一个值,所以我认为您只需要一次将行颜色闪烁一次即可.

Not really sure how they are related. You can only change a single value in the editor at one time, so I would think you only ever need to blink the row color for one row at a time.

无论如何,这里有一些(数十年)的旧代码,可让您指定多个单元格,行或列同时以不同的颜色闪烁.闪烁将继续,直到您自己停止为止.

Anyway here is some (decade) old code that allows you to specify multiple cells, rows or columns to blink with different colors all at the same time. The blinking continues until you stop it yourself.

所以我想您可以使用TableCellListener将新的单元格/行添加到致盲渲染器中.

So I guess you could use the TableCellListener to add a new cell/row to the blinding renderer.

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.Timer;
import javax.swing.*;
import javax.swing.table.*;

public class TableColor extends JFrame
{
    ColorRenderer colorRenderer;

    public TableColor()
    {
        String[] columnNames = {"Date", "String", "Integer", "Boolean"};
        Object[][] data =
        {
            {new Date(), "A", new Integer(1), new Boolean(true)},
            {new Date(), "B", new Integer(2), new Boolean(false)},
            {new Date(), "C", new Integer(3), new Boolean(true)},
            {new Date(), "D", new Integer(4), new Boolean(false)}
        };

        final DefaultTableModel model = new DefaultTableModel(data, columnNames);
        final JTable table = new JTable( model )
        {
            public Class getColumnClass(int column)
            {
                return getValueAt(0, column).getClass();
            }

            //  Apply background to existing renderer

            public Component prepareRenderer(
                TableCellRenderer renderer, int row, int column)
            {
                Component c = super.prepareRenderer(renderer, row, column);
                colorRenderer.setBackground(c, row, column);
                return c;
            }
        };
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane( table );
        getContentPane().add( scrollPane );

        JButton button = new JButton( "Add Row" );
        button.addActionListener( new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
//              model.addRow( createRow() );
                model.setRowCount( model.getRowCount() + 1 );
                int row = table.getRowCount() - 1;
//              table.changeSelection(row, 0, false, false);
                table.requestFocusInWindow();
                colorRenderer.setRowColor(row, Color.YELLOW);
            }
        });
        getContentPane().add(button, BorderLayout.SOUTH);

        //  Create blinking color renderer

        colorRenderer = new ColorRenderer( table );
        colorRenderer.setCellColor(1, 1, Color.RED);
        colorRenderer.setRowColor(1, Color.GREEN);
        colorRenderer.setRowColor(3, Color.GREEN);
        colorRenderer.setColumnColor(1, Color.BLUE);
        colorRenderer.startBlinking(1000);
    }

    public static void main(String[] args)
    {
        TableColor frame = new TableColor();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible(true);
    }

    /*
    **  Color cell background
    */
    class ColorRenderer implements ActionListener
    {
        private JTable table;
        private AbstractTableModel model;
        private Map colors;
        private boolean isBlinking = true;
        private Timer timer;
        private Point location;

        public ColorRenderer(JTable table)
        {
            this.table = table;
            model = (AbstractTableModel)table.getModel();
            colors = new HashMap();
            location = new Point();
        }

        public void setBackground(Component c, int row, int column)
        {
            //  Don't override the background color of a selected cell

            if ( table.isCellSelected(row, column) ) return;

            //  The default render does not reset the background color
            //  that was set for the previous cell, so reset it here

            if (c instanceof DefaultTableCellRenderer)
            {
                c.setBackground( table.getBackground() );
            }

            //  Don't highlight this time

            if ( !isBlinking ) return;

            //  In case columns have been reordered, convert the column number

            column = table.convertColumnIndexToModel(column);

            //  Get cell color

            Object key = getKey(row, column);
            Object o = colors.get( key );

            if (o != null)
            {
                c.setBackground( (Color)o );
                return;
            }

            //  Get row color

            key = getKey(row, -1);
            o = colors.get( key );

            if (o != null)
            {
                c.setBackground( (Color)o );
                return;
            }

            //  Get column color

            key = getKey(-1, column);
            o = colors.get( key );

            if (o != null)
            {
                c.setBackground( (Color)o );
                return;
            }

        }

        public void setCellColor(int row, int column, Color color)
        {
            Point key = new Point(row, column);
            colors.put(key, color);
        }

        public void setColumnColor(int column, Color color)
        {
            setCellColor(-1, column, color);
        }

        public void setRowColor(int row, Color color)
        {
            setCellColor(row, -1, color);
        }

        private Object getKey(int row, int column)
        {
            location.x = row;
            location.y = column;
            return location;
        }

        public void startBlinking(int interval)
        {
            timer = new Timer(interval, this);
            timer.start();
        }

        public void stopBlinking()
        {
            timer.stop();
        }

        public void actionPerformed(ActionEvent e)
        {
            isBlinking = !isBlinking;

            Iterator it = colors.keySet().iterator();

            while ( it.hasNext() )
            {
                Point key = (Point)it.next();
                int row = key.x;
                int column = key.y;

                if (column == -1)
                {
                    model.fireTableRowsUpdated(row, row);
                }
                else if (row == -1)
                {
                    int rows = table.getRowCount();

                    for (int i = 0; i < rows; i++)
                    {
                        model.fireTableCellUpdated(i, column);
                    }
                }
                else
                {
                    model.fireTableCellUpdated(row, column);
                }
            }
        }
    }
}

这篇关于DefualtTableCellRenderer中的JTable中的旧值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆