在我的apache tomcat 7服务器上有一个我想在ZK中用作控制台形式的文本框。现在,它的内容以编程方式更改时不会更新,但我想这样做。每当我的java更改字符串时,它应该及时显示它,但是如何?
(修改了ZK的现有代码)
我的index.zul:
<zk>
<window id="PDFmodifier" border="normal" height="98%"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('toolbox.pdfconverter.FileUploadVM')">
<label value="PDFmodifier"/>
<separator></separator>
<separator></separator>
<hbox>
<label value="Console log: " />
<textbox width="500px" height="400px" id="txt" readonly="true" multiline ="true" value="Press the Upload Button to upload any PDF file. PDFmodifier will cover the unwanted area. After processing, the showPDF button will be active and you can save the modified PDF"/>
<button label="Upload" upload="true"
onUpload="@command('onUploadPDF',upEvent=event)"> </button>
<button label="Show PDF" visible="@load(vm.fileuploaded)"
onClick="@command('showPDF')">
</button>
</hbox>
<iframe height="100%" width="100%" id="reportframe"
content="@bind(vm.fileContent)">
</iframe>
</window>
视图模型:
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Calendar;
import org.zkoss.bind.BindContext;
import org.zkoss.bind.annotation.AfterCompose;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.io.Files;
import org.zkoss.util.media.AMedia;
import org.zkoss.util.media.Media;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.UploadEvent;
import org.zkoss.zk.ui.select.Selectors;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;
public class FileUploadVM {
private String filePath;
private boolean fileuploaded = false;
AMedia fileContent;
@Wire("#test")
private Window win;
@Wire("#txt")
Textbox txt;
public AMedia getFileContent() {
return fileContent;
}
public void setFileContent(AMedia fileContent) {
this.fileContent = fileContent;
}
public boolean isFileuploaded() {
return fileuploaded;
}
public void setFileuploaded(boolean fileuploaded) {
this.fileuploaded = fileuploaded;
}
@AfterCompose
public void initSetup(@ContextParam(ContextType.VIEW) Component view) {
Selectors.wireComponents(view, this, false);
Executions.getCurrent().getDesktop().getWebApp().getConfiguration().setMaxUploadSize(10 * 1024);//for larger files
}
@Command
@NotifyChange("fileuploaded")
public void onUploadPDF(
@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx)
throws IOException {
UploadEvent upEvent = null;
Object objUploadEvent = ctx.getTriggerEvent();
if (objUploadEvent != null && (objUploadEvent instanceof UploadEvent)) {
upEvent = (UploadEvent) objUploadEvent;
}
if (upEvent != null) {
Media media = upEvent.getMedia();
Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH);
int day = now.get(Calendar.DAY_OF_MONTH);
int min = now.get(Calendar.MINUTE);
String fileName = year+"_"+month+"_"+day+"_"+min+".pdf";
filePath = Executions.getCurrent().getDesktop().getWebApp().getRealPath("/");
filePath = filePath + fileName;
System.out.println("filePath='"+filePath+"'");
Files.copy(new File(filePath), media.getStreamData());
PDFmodifier mod = new PDFmodifier(txt);//txt
filePath = mod.start(filePath);
System.out.println("Ergbnis-pfad='"+filePath+"'");
Messagebox.show("File Sucessfully altered. Press \"Show PDF\" to download file.");
fileuploaded = true;
}
}
@Command
@NotifyChange("fileContent")
public void showPDF() throws IOException {
File f = new File(filePath);
byte[] buffer = new byte[(int) f.length()];
FileInputStream fs = new FileInputStream(f);
fs.read(buffer);
fs.close();
ByteArrayInputStream is = new ByteArrayInputStream(buffer);
fileContent = new AMedia("report", "pdf", "application/pdf", is);
}
}
大大减少了java代码(这个问题需要更多但不需要):
import org.zkoss.zul.Textbox;
public class PDFmodifier {
String logText ="";
Textbox text;
public PDFmodifier(Textbox t)
{
text = t;
}
protected void printToTextbox(String txt)
{
logText += "\n"+txt;
text.setValue(logText);
}
}
这一切都有效,但我想改进它。感谢提前阅读。
编辑:
Index.zul
<zk xmlns:n="native" xmlns:c="client">
<?page title="RemoveKlausNote" ?>
<window id="RemoveKlausNote"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('toolbox.pdfconverter.FileUploadVM')"
title="Bioinfo Teaching Toolbox" border="normal" width="1000px" position="center,top" mode="embedded">
<hbox>
<label value="Console log: " />
<textbox width="500px" height="200px" readonly="true" value="@bind(vm.getLogText())" multiline ="true"/>
<button label="Upload" upload="true"
onUpload="@command('onUploadPDF',upEvent=event)"> </button>
<button label="Show PDF" visible="@load(vm.fileuploaded)"
onClick="@command('showPDF')">
</button>
</hbox>
<iframe height="100%" width="100%" id="reportframe"
content="@bind(vm.fileContent)">
</iframe>
</window>
视图模型:
public class FileUploadVM {
private String filePath;
private boolean fileuploaded = false;
AMedia fileContent;
@Wire("#test")
private Window win;
LogText logText = new LogText();
public AMedia getFileContent() {
return fileContent;
}
public void setFileContent(AMedia fileContent) {
this.fileContent = fileContent;
}
public boolean isFileuploaded() {
return fileuploaded;
}
public void setFileuploaded(boolean fileuploaded) {
this.fileuploaded = fileuploaded;
}
@AfterCompose
public void initSetup(@ContextParam(ContextType.VIEW) Component view) {
Selectors.wireComponents(view, this, false);
Executions.getCurrent().getDesktop().getWebApp().getConfiguration().setMaxUploadSize(10 * 1024);//for larger files
}
@NotifyChange("logText.log")
public void setLogText(String text) {
logText.setLog(text);
}
@NotifyChange("logText.log")
public String getLogText()
{
return logText.getLog();
}
@Command
@NotifyChange("fileuploaded")
public void onUploadPDF(
@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx)
throws IOException {
UploadEvent upEvent = null;
Object objUploadEvent = ctx.getTriggerEvent();
if (objUploadEvent != null && (objUploadEvent instanceof UploadEvent)) {
upEvent = (UploadEvent) objUploadEvent;
}
if (upEvent != null) {
Media media = upEvent.getMedia();
String webAppPath = Executions.getCurrent().getDesktop().getWebApp().getRealPath("/");
System.out.println("webAppPath='"+webAppPath+"'");
Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH);
int day = now.get(Calendar.DAY_OF_MONTH);
int min = now.get(Calendar.MINUTE);
String originalName = media.getName();
String fileName = originalName +year+"_"+month+"_"+day+"_"+min+".pdf";
String tmpPath = PDFmodifier.getTemp();
if (!tmpPath.endsWith(File.separatorChar+"")) tmpPath = tmpPath + File.separator;
filePath = tmpPath + fileName;
System.out.println("filePath='"+filePath+"'");
Files.copy(new File(filePath), media.getStreamData());
filePath = new PDFmodifier(logText).start(filePath);
System.out.println("Ergbnis-pfad='"+filePath+"'");
Messagebox.show("File Sucessfully altered. Press \"Show PDF\" to download file.");
fileuploaded = true;
}
}
LogText对象:
public class LogText {
public String log;
public LogText()
{
log ="Press the Upload Button to upload any PDF file. PDFmodifier will cover the unwanted area. After processing, the showPDF button will be active and you can save the modified PDF";
}
public void setLog(String txt)
{
log += "\n"+txt;
}
public String getLog()
{
return log;
}
}
PDFmodifier(我不妨展示我的核心方法start()):
protected void printToTextbox(String txt)
{
log.setLog("\n"+txt);
}
public String start(String uploadFile) throws IOException
{
setStringVariables(uploadFile);
System.out.println("Processing inputFile='"+inputFile+"'");
File f = new File(inputFile);
if (!f.exists()) {
System.err.println("inputFile not found)");
return null;
}
long startTime = System.currentTimeMillis();
//file can be opened and normally processed
if(accessChecker(inputFile)){
coverWithRectangle(inputFile, outputFile) ;
return outputFile;
}
//file needs further work
else
{
printToTextbox("Accessing PDFsam for split...");
if (createDirectory(outputDir)) {
long startTimeSplit = System.currentTimeMillis();
boolean splitOk = splitPDF(inputFile, outputDir);
long endTimeSplit = System.currentTimeMillis();
printToTextbox("Time for splitting [ms]: "+(endTimeSplit-startTimeSplit));
if (!splitOk) {
printToTextbox("PDF couldn't be split. Exiting.");
return null;
}
else
{
long startTimeMerge = System.currentTimeMillis();
boolean mergeOk = mergePDF(getAllFiles(),tempPDF,tempCSV);
long endTimeMerge = System.currentTimeMillis();
printToTextbox("Time for merging [ms]: "+(endTimeMerge-startTimeMerge));
if (mergeOk) {
coverWithRectangle(tempPDF, outputFile);
deleteTrash();
} else {
printToTextbox("ERROR: merge failed!");
}
}
}
writeLog(outputFile);
long endTime = System.currentTimeMillis();
printToTextbox("Total time needed [ms]: "+(endTime-startTime));
printToTextbox("outputFile='"+outputFile+"'");
return outputFile;
}
编辑2:
祖尔:
<textbox width="500px" height="200px" readonly="true" value="@bind(vm.logText)" multiline ="true"/>
<timer id="timer" delay="50" repeats="true" onTimer="@command('refreshTextbox')" />
视图模型:
String logText;
LogText log = new LogText();
@NotifyChange("logText")
public void setLogText(String txt)
{
log.log ="\n"+txt;
logText = log.log;
}
@NotifyChange("logText")
public String getLogText()
{
logText = log.log;
return logText;
}
@Command
public void refreshTextbox()
{
logText = log.log;
BindUtils.postNotifyChange(null,null,this,"logText");
}
viewmodel将Textlog对象传递给Pdfmodifier的新实例。一个解决这个问题的尝试。
答案 0 :(得分:2)
您正在混合两种类型,MVVM和MVC。 窗口和文本框以MVC方式使用。
您可以更轻松地完成此任务:
在您的VM中创建:
public class MainActivity extends Activity {
ProgressDialog mDialog;
....
protected void onCreate(){
//Add remaining code
if(mDialog==null){
showLoadingDialog(//send in params);
}
asyncTask.execute(apiRequestModel);
}
public void showLoadingDialog(String title, String message){
mDialog= new ProgressDialog(this);
mDialog.setTitle(title);
mDialog.setMessage(message);
mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mDialog.setIndeterminate(true);
mDialog.setProgress(0);
mDialog.setCancelable(false);
mDialog.show();
} //Close dialog box code
public class GetAPIResponse extends AsyncTask<APIRequestModel, Void, String> {
//Custom functions that you already have. Leave doInBackground as it is
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(mDialog!=null){
mDialog.dismiss();
}
}
}//Close async task
}//Close Activity
并提供getter和setter。
在viewmodel中更改为:
private String textField = "Press the Upload Button to upload any PDF file. PDFmodifier will cover the unwanted area. After processing, the showPDF button will be active and you can save the modified PDF";
现在,当想要将更改保留到GUI时,您可以使用
<textbox width="500px" height="400px" id="txt" readonly="true" multiline ="true" value=@bind(vm.textField)"/>
但这只适用于制定者和命令。
您可以在viewmodel中的其他方法中执行此操作,如:
@NotifyChange("textField")
如果您的文本框需要在文件上载繁忙时更新一次,则需要单独的线程。
如果没有,你几乎就在那里:
BindUtils.postNotifyChange(null,null,this,"textField");
在这里删除了notifychanged,不需要和完美的解决方案来显示文本。
public void setLogText(String text) {
logText.setLog(text);
}
public String getLogText() {
return logText.getLog();
}
将logText的notifychange添加到此命令。
现在还有其他一些改进:
@Command
@NotifyChange({"fileuploaded","logText"})
public void onUploadPDF(
@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx)
throws IOException {
UploadEvent upEvent = null;
Object objUploadEvent = ctx.getTriggerEvent();
if (objUploadEvent != null && (objUploadEvent instanceof UploadEvent)) {
upEvent = (UploadEvent) objUploadEvent;
}
if (upEvent != null) {
Media media = upEvent.getMedia();
String webAppPath = Executions.getCurrent().getDesktop().getWebApp().getRealPath("/");
System.out.println("webAppPath='"+webAppPath+"'");
Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH);
int day = now.get(Calendar.DAY_OF_MONTH);
int min = now.get(Calendar.MINUTE);
String originalName = media.getName();
String fileName = originalName +year+"_"+month+"_"+day+"_"+min+".pdf";
String tmpPath = PDFmodifier.getTemp();
if (!tmpPath.endsWith(File.separatorChar+"")) tmpPath = tmpPath + File.separator;
filePath = tmpPath + fileName;
System.out.println("filePath='"+filePath+"'");
Files.copy(new File(filePath), media.getStreamData());
filePath = new PDFmodifier(logText).start(filePath);
System.out.println("Ergbnis-pfad='"+filePath+"'");
Messagebox.show("File Sucessfully altered. Press \"Show PDF\" to download file.");
fileuploaded = true;
}
你不要在虚拟机中询问upEvent,只需将其删除即可。
<button label="Upload" upload="true"
onUpload="@command('onUploadPDF',upEvent=event)"> </button>
可能是这样的:
public void onUploadPDF(
@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx)
throws IOException {
因为您唯一要做的就是从bindContext获取触发器事件,因此无需获取该对象,并且它会删除方法中的大量样板代码。
看起来你需要一个单独的线程来处理。
I created a fiddle所以你可以看到我是怎么做到的。
但如果链接死了:
public void onUploadPDF(
@ContextParam(ContextType.TRIGGER_EVENT) UploadEvent evt)
throws IOException {
和zul: