/**
* Copyright (C) 2010 EdgyTech LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.edgytech.umongo;
import com.edgytech.swingfast.*;
import java.awt.Component;
import java.awt.Rectangle;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javax.swing.SwingUtilities;
/**
*
* @author antoine
*/
public class TextView extends Zone implements EnumListener, TabInterface, Runnable {
enum Item {
textArea,
tabDiv,
tabTitle,
tabClose,
refresh,
export,
tools,
startAutoUpdate,
stopAutoUpdate
}
TabbedDiv tabbedDiv;
Thread updateThread;
int updateInterval;
int updateCount;
boolean running;
DbJob job;
public TextView(String id, String label, DbJob job) {
try {
xmlLoad(Resource.getXmlDir(), Resource.File.textView, null);
} catch (Exception ex) {
getLogger().log(Level.SEVERE, null, ex);
}
setEnumBinding(Item.values(), this);
setId(id);
setLabel(label);
this.job = job;
setStringFieldValue(Item.tabTitle, label);
((MenuItem) getBoundUnit(Item.refresh)).enabled = true;
((MenuItem) getBoundUnit(Item.startAutoUpdate)).enabled = true;
}
/**
* create a doc view with static document
*
* @param id
* @param label
* @param job
* @param root
* @param doc
*/
public TextView(String id, String label, DbJob job, String text) {
this(id, label, job);
if (text != null) {
setContent(text);
}
}
public void close(ButtonBase button) {
tabbedDiv.removeTab(this);
}
void addToTabbedDiv() {
tabbedDiv = UMongo.instance.getTabbedResult();
tabbedDiv.addTab(this, true);
}
public void actionPerformed(Enum enm, XmlComponentUnit unit, Object src) {
}
// public void export(ButtonBase button) throws IOException {
// // export should be run in thread, to prevent concurrent mods
// ExportDialog dia = UMongo.instance.getGlobalStore().getExportDialog();
// if (!dia.show()) {
// return;
// }
// final DocumentSerializer ds = dia.getDocumentSerializer();
// try {
// DefaultMutableTreeNode root = getTree().getTreeNode();
// for (int i = 0; i < root.getChildCount(); ++i) {
// DefaultMutableTreeNode child = (DefaultMutableTreeNode) root.getChildAt(i);
// Object obj = child.getUserObject();
// DBObject doc = null;
// if (obj instanceof DBObject) {
// doc = (DBObject) obj;
// } else if (obj instanceof TreeNodeDocumentField) {
// doc = (DBObject) ((TreeNodeDocumentField) obj).getValue();
// } else if (obj instanceof TreeNodeDocument) {
// doc = ((TreeNodeDocument) obj).getDBObject();
// }
// if (doc != null) {
// ds.writeObject(doc);
// }
// }
// } finally {
// ds.close();
// }
// }
public Component getTabComponent() {
return getComponentBoundUnit("tabDiv").getComponent();
}
TextArea getTextArea() {
return (TextArea) getBoundUnit(Item.textArea);
}
public void startAutoUpdate(ButtonBase button) {
AutoUpdateDialog dia = UMongo.instance.getGlobalStore().getAutoUpdateDialog();
if (!dia.show()) {
return;
}
if (updateThread != null) {
stopAutoUpdate(null);
}
updateThread = new Thread(this);
updateInterval = dia.getComponentIntFieldValue(AutoUpdateDialog.Item.autoInterval);
updateCount = dia.getComponentIntFieldValue(AutoUpdateDialog.Item.autoCount);
running = true;
updateThread.start();
getComponentBoundUnit(Item.stopAutoUpdate).enabled = true;
getComponentBoundUnit(Item.stopAutoUpdate).updateComponent();
}
public void stopAutoUpdate(ButtonBase button) {
running = false;
try {
updateThread.interrupt();
updateThread.join();
} catch (InterruptedException ex) {
}
updateThread = null;
getComponentBoundUnit(Item.stopAutoUpdate).enabled = false;
getComponentBoundUnit(Item.stopAutoUpdate).updateComponent();
}
public void run() {
int i = 0;
while (running) {
try {
DbJob job = getRefreshJob();
final DbJob fjob = job;
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
fjob.addJob();
}
});
try {
fjob.join();
} catch (InterruptedException ex) {
getLogger().log(Level.WARNING, null, ex);
} catch (ExecutionException ex) {
getLogger().log(Level.WARNING, null, ex);
}
if (updateCount > 0 && ++i >= updateCount) {
break;
}
Thread.sleep(updateInterval * 1000);
} catch (Exception ex) {
getLogger().log(Level.SEVERE, null, ex);
}
}
getLogger().log(Level.INFO, "Ran " + i + " updates");
}
public void refresh(ButtonBase button) {
getRefreshJob().addJob();
}
public DbJob getRefreshJob() {
if (job == null) {
return null;
}
DbJob newJob = new DbJob() {
String result;
@Override
public Object doRun() throws Exception {
result = (String) job.doRun();
return null;
}
@Override
public String getNS() {
return job.getNS();
}
@Override
public String getShortName() {
return job.getShortName();
}
@Override
public void wrapUp(Object res) {
super.wrapUp(res);
if (res == null && result != null) {
// setContent(result);
// getTextArea().updateComponent();
appendContent(result);
// panel info may need to be refreshed
if (job.getPanel() != null) {
job.getPanel().refresh();
}
}
}
};
return newJob;
}
public void setContent(String text) {
setStringFieldValue(Item.textArea, text);
}
/**
* Following method doesnt really work because the log buffer is a short moving window
*/
public void swapContent(String text) {
TextArea ta = (TextArea) getBoundUnit(Item.textArea);
// int pos = ta.getTextArea().getCaretPosition();
int val = ta.getComponent().getVerticalScrollBar().getValue();
int max = ta.getComponent().getVerticalScrollBar().getMaximum();
int vis = ta.getComponent().getVerticalScrollBar().getVisibleAmount();
setStringFieldValue(Item.textArea, text);
updateComponent();
// scroll resets, set it back if not to close to the end
// System.out.println(val + " " + max + " " + vis);
if (val < max - vis)
ta.getComponent().getVerticalScrollBar().setValue(val);
}
public void appendContent(String text) {
final TextArea ta = (TextArea) getBoundUnit(Item.textArea);
// since logs are moving window, need to find the spot within new log
String old = ta.getComponentStringValue();
int last = old.lastIndexOf("\n", old.length() - 5);
String lastLine = old.substring(last + 1);
int pos = text.indexOf(lastLine);
if (pos >= 0)
text = text.substring(pos + lastLine.length());
final int val = ta.getComponent().getVerticalScrollBar().getValue();
int max = ta.getComponent().getVerticalScrollBar().getMaximum();
int vis = ta.getComponent().getVerticalScrollBar().getVisibleAmount();
Rectangle rect = ta.getComponent().getVisibleRect();
ta.getTextArea().append(text);
// scroll resets, set it back if not to close to the end, needs to be done at later time in EVT
if (val < max - 2 * vis) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ta.getComponent().getVerticalScrollBar().setValue(val);
}
});
}
}
}