残りのメソッド
import java.awt.*;
import java.lang.reflect.*;
import java.util.*;
import javax.swing.*;
/**
* Thread responsible for publishing changes to the Model. Sleeps for a defined
* amount of time, waits for no activity in the UI and then users invokeAndWait
* to publish changes.
*/
public class UpdateThread extends Thread {
private int sleepTime;
private int eqSleepTime;
private int threshhold;
private boolean updatesEnabled;
private Runnable publishRunnable;
private Runnable emptyRunnable;
private GeneratorThread generator;
private CTTableModel model;
private Map<?, ?> lastData;
private long notifyTime;
private long paintTime;
private int updateCount;
private boolean done;
public UpdateThread(GeneratorThread generator, CTTableModel model,
int sleepTime, int eqSleepTime, int threshhold) {
super();
setPriority(Thread.MIN_PRIORITY);
this.sleepTime = sleepTime;
this.eqSleepTime = eqSleepTime;
updatesEnabled = true;
this.threshhold = threshhold;
this.generator = generator;
this.model = model;
publishRunnable = new Runnable() {
// Runnable used to publish changes to the event dispatching thread
@Override
public void run() {
publishChangesOnEventDispatchingThread();
}
};
// Empty runnable, used to wait until the event dispatching thread
// has finished processing any pending events.
emptyRunnable = new Runnable() {
@Override
public void run() {
}
};
}
@Override
public void interrupt() {
done = true;
super.interrupt();
}
@Override
public void run() {
while (!isInterrupted() && !done) {
try {
sleep(sleepTime);
publishChanges();
} catch (InterruptedException ie) {
}
}
System.out.println("UpdateThread done");
}
/**
* Publishes changes on the event dispatching thread when the system isn't
* busy. This blocks the caller until the changes have been published.
*/
private void publishChanges() {
synchronized (this) {// Wait until the user isn't scrolling
while (!updatesEnabled) {
try {
wait();
} catch (InterruptedException ie) {
}
}
}
EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
// And wait until there are no pending events.
while (queue.peekEvent() != null) {
try {
sleep(eqSleepTime);
} catch (InterruptedException ie) {
}
}
final long start = System.currentTimeMillis();
try {
SwingUtilities.invokeAndWait(publishRunnable);
// publish the changes on the event dispatching thread
} catch (InterruptedException ie) {
} catch (InvocationTargetException ite) {
}
try {
// Wait until the system has completed processing of any events we
// triggered as part of publishing changes.
SwingUtilities.invokeAndWait(emptyRunnable);
} catch (InterruptedException ie) {
} catch (InvocationTargetException ite) {
}
final long end = System.currentTimeMillis();
try {// Update the display
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
Main.totalUpdateTime.setText("Total: "
+ Integer.toString((int) (end - start)));
Main.notifyTime.setText("Notify: "
+ Integer.toString((int) notifyTime));
Main.paintTime.setText("Paint: "
+ Integer.toString((int) paintTime));
Main.updateCount.setText("Updated: "
+ Integer.toString((int) updateCount));
}
});
} catch (InterruptedException ie) {
} catch (InvocationTargetException ite) {
}
}
/**
* Does the actual publishing of changes.
*/
private void publishChangesOnEventDispatchingThread() {
long start = System.currentTimeMillis();
model.setBatchUpdates(true);
Map<?, ?> data = generator.getData();
boolean notify = !(data.size() > threshhold ||
(lastData != null && lastData.size() + data.size() > threshhold));
updateCount = data.size();
if (lastData != null) {
updateCount += lastData.size();
}//Reset the data for the last set of changes we did, this forces the cells to change color.
if (lastData != null) {
publishData(lastData, true, notify);
Iterator<?> dataIterator = lastData.keySet().iterator();
while (dataIterator.hasNext()) {
DataChange.releaseDataChange((DataChange) dataIterator.next());
}
lastData.clear();
}
publishData(data, false, notify);// Publish the current set of data.
model.setBatchUpdates(false);
if (!notify) {
model.fireTableDataChanged();
}
lastData = data;
long end = System.currentTimeMillis();
notifyTime = (end - start);
start = System.currentTimeMillis();
RepaintManager.currentManager(null).paintDirtyRegions();
end = System.currentTimeMillis();
paintTime = (end - start);
}
/**
* Publish the passed in set of data.
*/
private void publishData(Map<?, ?> data, boolean negate, boolean notify) {
Iterator<?> dataIterator = data.keySet().iterator();
while (dataIterator.hasNext()) {
DataChange change = (DataChange) dataIterator.next();
Object value = data.get(change);
if (negate) {
value = new Integer(((Integer) value).intValue() * -1);
}
model.set(change.getData(), change.getColumn(), value, notify);
}
}
/**
* If enable is true, we are allowed to publish changes, otherwise we
* aren't.
*
* @param enable
*/
public void setUpdatesEnabled(boolean enable) {
synchronized (this) {
updatesEnabled = enable;
if (updatesEnabled) {
notify();
}
}
}
public boolean getUpdatesEnabled() {
return updatesEnabled;
}
}
.
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
/**
* VisibleTableModelEvent adds the method isVisible to test if the cell
* identified by the event is visible.
*/
public class VisibleTableModelEvent extends TableModelEvent {
private static final long serialVersionUID = 1L;
private Point tmpPoint;
// This implementation caches the information for one JTable, it is
// certainly possible to cache it for more than one should
// you have this need.
private boolean valid;
private int firstVisRow;
private int lastVisRow;
private int firstVisCol;
private int lastVisCol;
public VisibleTableModelEvent(TableModel source) {
super(source, 0, 0, 0, UPDATE);
tmpPoint = new Point();
}
/**
* Resets the underlying fields of the TableModelEvent. This assumes no ONE
* is going to cache the TableModelEvent.
*
* @param row
* @param col
*/
public void set(int row, int col) {
firstRow = row;
lastRow = row;
column = col;
}
/**
* Invoked to indicate the visible rows/columns need to be recalculated
* again.
*/
public void reset() {
valid = false;
}
public boolean isVisible(JTable table) {
if (!valid) {// Determine the visible region of the table.
Rectangle visRect = table.getVisibleRect();
tmpPoint.x = visRect.x;
tmpPoint.y = visRect.y;
firstVisCol = table.columnAtPoint(tmpPoint);
firstVisRow = table.rowAtPoint(tmpPoint);
tmpPoint.x += visRect.width;
tmpPoint.y += visRect.height;
lastVisCol = table.columnAtPoint(tmpPoint);
if (lastVisCol == -1) {
lastVisCol = table.getColumnCount() - 1;
}
if ((lastVisRow = table.rowAtPoint(tmpPoint)) == -1) {
lastVisRow = table.getRowCount();
}
valid = true;
}
return (firstRow >= firstVisRow && firstRow <= lastVisRow && column
>= firstVisCol && column <= lastVisCol);
}
}