2016-05-03 3 views
0

Я пытался в течение нескольких недель, чтобы получить Cell в JTable мигать, изменяя цвет фона с RGBtoHSV, я могу прошить одну строку, используя метод, который я нашел поиска в Интернете, но когда он приходит к нескольким строкам, он, похоже, не работает.Прежнее значение в JTable в DefualtTableCellRenderer

Я попытался создать собственный класс рендеринга, но все же не смог найти способ иметь старое значение с новым значением, чтобы со вспышкой ячейки, когда oldvalue < newvalue.

Все мои попытки получить oldValue для ячейки потерпели неудачу, поэтому ее там нет. Я пробовал TableCellListener, класс, который я нашел с помощью моего googlefu, но я понятия не имел, как реализовать его в рендерере, хотя его реализация в таблице была успешной.

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); 

EDIT: Я пытаюсь добиться чего-то вроде TableCellListener .class я нашел во время поиска, но в 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); 
    } 
} 

}

Я использовал celllistener в моей JTable так:

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); 

Я пытаюсь получить этот класс работает в JTable: видеообработки, так что я могу прошить Cell, когда старое значение меньше, чем новое значение, которое было вытащено из базы данных.

EDIT2: Я надеюсь, что кто-то может пролить свет на то, как я могу получить старое значение в рендерере или другой метод мигания таблиц ячеек.

+0

Для получения более подробной помощи, отправьте сообщение [MCVE] или [Short, Self Contained, Correct Example] (http://www.sscce.org/). –

+0

@AndrewThompson Я попытался дать немного больше информации. – SunnyH

+0

* «дайте немного больше информации» * Дополнительная информация, которую я предложил, была MCVE. Как это происходит? –

ответ

1

Вы, кажется, есть два требования

  1. , как я могу получить старое значение
  2. но когда дело доходит до нескольких строк, не похоже на работу.

Не совсем уверен, как они связаны. Вы можете изменить только одно значение в редакторе за один раз, поэтому я бы подумал, что вам когда-либо понадобится только мигать цвет строки для одной строки за раз.

В любом случае, это несколько (десятичный) старый код, который позволяет вам указывать несколько ячеек, строк или столбцов, чтобы одновременно мигать разными цветами. Мигание продолжается до тех пор, пока вы не остановите его самостоятельно.

Так что, я думаю, вы могли бы использовать TableCellListener, чтобы добавить новую ячейку/строку в ослепляющий рендерер.

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); 
       } 
      } 
     } 
    } 
} 
0

Средство визуализации ячеек предназначено для повторного использования для всех ячеек. Он сам получается из JLabel и многократно используется для рендеринга каждой ячейки.

Это означает, что при вызове нужно подготовить графический интерфейс для текущей ячейки. Это вы сделали.

Чтобы иметь несколько ячеек, мигающих при определенных изменениях значений, нужно сохранить это состояние либо в каждой ячейке, либо сказать в глобальном наборе или карте координат ячейки мигающих точек.

Скажем, если у нас есть 3 состояния мигания 0, 1, 2, можно сопоставить целое число.

Идея заключается в следующем коде:

Map<Point, Integer> cellsFlash = new HashMap<>(); 

// In change listener, when needing flashing a cell: 
cellsFlash.put(new Point(column, row), 0); 

// In the renderer: 
Point cellRef = new Point(column, row); 
Integer flashOpt = cellsFlash.get(cellRef); 
if (flashOpt != null) { 
    int flash = flashOpt; 
    switch (flash) { ... } 
    ++flash; 
    if (flash > 2) { 
     // End animation: 
     cellsFlash.remove(cellRef); 
    } else { 
     // Next animation step: 
     cellsFlash.put(cellRef, flash); 
    } 
    table.repaint(50L); // Or such 
} 

Конечно, вы, вероятно, хотите немного более сложную анимацию.