Skip to content
Snippets Groups Projects
Commit a721e90e authored by Radek Ošlejšek's avatar Radek Ošlejšek
Browse files

Resolve "Make logging into the OutputWindow available from low-level modules"

parent 42761201
No related branches found
No related tags found
No related merge requests found
...@@ -18,7 +18,7 @@ public class RandomStrategy extends UndersamplingStrategy { ...@@ -18,7 +18,7 @@ public class RandomStrategy extends UndersamplingStrategy {
/** /**
* Constructor for PERCENTAGE undersampling type. * Constructor for PERCENTAGE undersampling type.
* *
* @param perc Percentage - a value in (0.0, 1.0&gtl * @param perc Percentage - a value in (0.0, 1.0>
* @throws IllegalArgumentException if the input parameter is wrong * @throws IllegalArgumentException if the input parameter is wrong
*/ */
public RandomStrategy(double perc) { public RandomStrategy(double perc) {
......
package cz.fidentis.analyst.core; package cz.fidentis.analyst.core;
import cz.fidentis.analyst.Logger;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.text.SimpleDateFormat; import java.util.List;
import java.time.Duration;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTextArea; import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import org.openide.windows.TopComponent; import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager; import org.openide.windows.WindowManager;
/** /**
* Wrapper for default output window of the Java Netbeans Platform application. * Wrapper of the default Java Netbeans Platform output window.
* It enables to write debug messages into the window. * This wrapper runs in the worker thread, reads messages logged through
* the {@link cz.fidentis.analyst.Logger} and displays them in the output window.
*
* The {@code OutputWindow} is currently executed from
* the {@link cz.fidentis.analyst.core.ProjectTopComp}, which is always presented.
* *
* @author Radek Oslejsek * @author Radek Oslejsek
*/ */
public class OutputWindow { public class OutputWindow extends SwingWorker<String, String> {
private static JTextArea textArea; private static JTextArea textArea;
private long lastTime = System.currentTimeMillis();
protected OutputWindow() {
initTextArea();
}
/** /**
* Prints the message. * Constructor.
*
* @param msg Message to be printed
*/ */
public static void print(String msg) { public OutputWindow() {
JTextArea ta = initTextArea(); TopComponent outputWin = WindowManager.getDefault().findTopComponent("output");
ta.setText(ta.getText() textArea = new JTextArea();
+ new SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis()) JScrollPane sp = new JScrollPane(textArea);
+ " [duration unknown]: " outputWin.add(sp, BorderLayout.CENTER);
+ msg.trim()
+ System.lineSeparator()
);
} }
/** /**
* Starts measuring of some operation. * Reads messages of the {@code Logger} in the background and re-sends them
* Call {@link #printDuration(java.lang.String)} on returned OutputWindow * the {@link #process(java.util.List)} method.
* to print the measured duration.
* *
* @return An object used to print measured duration and message * @return Complete text displayed in the output window.
* @throws Exception
*/ */
public static OutputWindow measureTime() { @Override
OutputWindow ret = new OutputWindow(); protected String doInBackground() throws Exception {
ret.lastTime = System.currentTimeMillis(); String line = Logger.reader().readLine();
return ret; while (line != null) {
publish(line);
line = Logger.reader().readLine();
}
return textArea.getText();
} }
/** /**
* Prints the message about an operation and the duration of the operation. * Takes text lines process by the {@link #doInBackground()} method and
* The duration is computed as the difference between current system time and * adds them to the output window.
* the time of calling {@link #measureTime()}. The time difference is measured in
* milliseconds and printed as [+mm:ss.SSS] where mm=minutes, ss=seconds,
* and SSS=milliseconds.
* *
* @param msg Message to be printed * @param chunks process lines
*/ */
public void printDuration(String msg) { @Override
Duration duration = Duration.ofMillis(System.currentTimeMillis() - lastTime); protected void process(List<String> chunks) {
textArea.setText(textArea.getText() StringBuilder sb = new StringBuilder();
+ new SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis()) sb.append(textArea.getText());
+ " [duration " chunks.forEach(str -> {
+ String.format( sb.append(str + System.lineSeparator());
"%02d:%02d.%03d", });
duration.toMinutes(), textArea.setText(sb.toString());
duration.toSecondsPart(),
duration.toMillisPart())
+ "]: "
+ msg.trim()
+ System.lineSeparator()
);
}
protected static JTextArea initTextArea() {
if (textArea == null) {
TopComponent outputWin = WindowManager.getDefault().findTopComponent("output");
textArea = new JTextArea();
JScrollPane sp = new JScrollPane(textArea);
outputWin.add(sp, BorderLayout.CENTER);
}
return textArea;
} }
} }
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package cz.fidentis.analyst.core; package cz.fidentis.analyst.core;
import cz.fidentis.analyst.Logger;
import org.netbeans.api.settings.ConvertAsProperties; import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.awt.ActionID; import org.openide.awt.ActionID;
import org.openide.awt.ActionReference; import org.openide.awt.ActionReference;
...@@ -84,6 +80,10 @@ public final class ProjectTopComp extends TopComponent { ...@@ -84,6 +80,10 @@ public final class ProjectTopComp extends TopComponent {
putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE); putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
putClientProperty(TopComponent.PROP_DRAGGING_DISABLED, Boolean.TRUE); putClientProperty(TopComponent.PROP_DRAGGING_DISABLED, Boolean.TRUE);
putClientProperty(TopComponent.PROP_UNDOCKING_DISABLED, Boolean.TRUE); putClientProperty(TopComponent.PROP_UNDOCKING_DISABLED, Boolean.TRUE);
// Execute OutputWindow in the worker thread so that messages
// logged via Logger are displayed in the output window
(new OutputWindow()).execute();
} }
/** /**
...@@ -671,7 +671,7 @@ public final class ProjectTopComp extends TopComponent { ...@@ -671,7 +671,7 @@ public final class ProjectTopComp extends TopComponent {
if (files == null) { if (files == null) {
System.out.print("No file chosen."); System.out.print("No file chosen.");
} else { } else {
OutputWindow out = OutputWindow.measureTime(); Logger out = Logger.measureTime();
for (File file : files) { for (File file : files) {
String faceId = HumanFaceFactory.instance().loadFace(file); String faceId = HumanFaceFactory.instance().loadFace(file);
HumanFace face = HumanFaceFactory.instance().getFace(faceId); HumanFace face = HumanFaceFactory.instance().getFace(faceId);
......
package cz.fidentis.analyst.curvature; package cz.fidentis.analyst.curvature;
import cz.fidentis.analyst.Logger;
import cz.fidentis.analyst.canvas.Canvas; import cz.fidentis.analyst.canvas.Canvas;
import cz.fidentis.analyst.core.ControlPanelAction; import cz.fidentis.analyst.core.ControlPanelAction;
import cz.fidentis.analyst.core.OutputWindow;
import cz.fidentis.analyst.visitors.mesh.Curvature; import cz.fidentis.analyst.visitors.mesh.Curvature;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import javax.swing.JComboBox; import javax.swing.JComboBox;
...@@ -77,7 +77,7 @@ public class CurvatureAction extends ControlPanelAction { ...@@ -77,7 +77,7 @@ public class CurvatureAction extends ControlPanelAction {
protected void setHeatmap() { protected void setHeatmap() {
if (visitor == null) { // compute missing curvature if (visitor == null) { // compute missing curvature
OutputWindow out = OutputWindow.measureTime(); Logger out = Logger.measureTime();
this.visitor = new Curvature(); this.visitor = new Curvature();
getPrimaryDrawableFace().getModel().compute(visitor); getPrimaryDrawableFace().getModel().compute(visitor);
out.printDuration("Computation of curvature for a model with " out.printDuration("Computation of curvature for a model with "
......
package cz.fidentis.analyst.distance; package cz.fidentis.analyst.distance;
import com.jogamp.opengl.GL2; import com.jogamp.opengl.GL2;
import cz.fidentis.analyst.Logger;
import cz.fidentis.analyst.canvas.Canvas; import cz.fidentis.analyst.canvas.Canvas;
import cz.fidentis.analyst.core.LoadedActionEvent; import cz.fidentis.analyst.core.LoadedActionEvent;
import cz.fidentis.analyst.core.ControlPanelAction; import cz.fidentis.analyst.core.ControlPanelAction;
import cz.fidentis.analyst.core.ControlPanelBuilder; import cz.fidentis.analyst.core.ControlPanelBuilder;
import cz.fidentis.analyst.core.OutputWindow;
import cz.fidentis.analyst.feature.FeaturePoint; import cz.fidentis.analyst.feature.FeaturePoint;
import cz.fidentis.analyst.feature.FeaturePointType; import cz.fidentis.analyst.feature.FeaturePointType;
import cz.fidentis.analyst.mesh.core.MeshFacet; import cz.fidentis.analyst.mesh.core.MeshFacet;
...@@ -267,7 +267,7 @@ public class DistanceAction extends ControlPanelAction { ...@@ -267,7 +267,7 @@ public class DistanceAction extends ControlPanelAction {
throw new UnsupportedOperationException(strategy); throw new UnsupportedOperationException(strategy);
} }
OutputWindow out = OutputWindow.measureTime(); Logger out = Logger.measureTime();
this.visitor = new HausdorffDistancePrioritized(getPrimaryDrawableFace().getModel(), this.visitor = new HausdorffDistancePrioritized(getPrimaryDrawableFace().getModel(),
featurePoints, featurePoints,
useStrategy, useStrategy,
......
package cz.fidentis.analyst.registration; package cz.fidentis.analyst.registration;
import cz.fidentis.analyst.Logger;
import cz.fidentis.analyst.canvas.Canvas; import cz.fidentis.analyst.canvas.Canvas;
import cz.fidentis.analyst.core.ControlPanelAction; import cz.fidentis.analyst.core.ControlPanelAction;
import cz.fidentis.analyst.core.OutputWindow;
import cz.fidentis.analyst.face.HumanFace; import cz.fidentis.analyst.face.HumanFace;
import cz.fidentis.analyst.feature.FeaturePoint; import cz.fidentis.analyst.feature.FeaturePoint;
import cz.fidentis.analyst.icp.IcpTransformation; import cz.fidentis.analyst.icp.IcpTransformation;
...@@ -258,7 +258,7 @@ public class RegistrationAction extends ControlPanelAction { ...@@ -258,7 +258,7 @@ public class RegistrationAction extends ControlPanelAction {
} }
protected void applyICP() { protected void applyICP() {
OutputWindow out = OutputWindow.measureTime(); Logger out = Logger.measureTime();
IcpTransformer visitor = new IcpTransformer(getPrimaryDrawableFace().getModel(), maxIterations, scale, error, undersampling); IcpTransformer visitor = new IcpTransformer(getPrimaryDrawableFace().getModel(), maxIterations, scale, error, undersampling);
getSecondaryDrawableFace().getModel().compute(visitor); // NOTE: the secondary face is physically transformed getSecondaryDrawableFace().getModel().compute(visitor); // NOTE: the secondary face is physically transformed
...@@ -306,7 +306,7 @@ public class RegistrationAction extends ControlPanelAction { ...@@ -306,7 +306,7 @@ public class RegistrationAction extends ControlPanelAction {
* otherwise set color to default * otherwise set color to default
*/ */
private void calculateFeaturePoints() { private void calculateFeaturePoints() {
OutputWindow.print("Calculation of feature points"); Logger.print("Calculation of feature points");
if (getPrimaryDrawableFace() == null) { // scene not yet initiated if (getPrimaryDrawableFace() == null) { // scene not yet initiated
return; return;
...@@ -346,7 +346,7 @@ public class RegistrationAction extends ControlPanelAction { ...@@ -346,7 +346,7 @@ public class RegistrationAction extends ControlPanelAction {
} }
private void calculateHausdorffDistance() { private void calculateHausdorffDistance() {
OutputWindow out = OutputWindow.measureTime(); Logger out = Logger.measureTime();
HumanFace primFace = getScene().getHumanFace(0); HumanFace primFace = getScene().getHumanFace(0);
primFace.computeKdTree(false); primFace.computeKdTree(false);
...@@ -467,7 +467,7 @@ public class RegistrationAction extends ControlPanelAction { ...@@ -467,7 +467,7 @@ public class RegistrationAction extends ControlPanelAction {
} }
if (hdVisitor == null) { if (hdVisitor == null) {
OutputWindow out = OutputWindow.measureTime(); Logger out = Logger.measureTime();
this.hdVisitor = new HausdorffDistance(getPrimaryDrawableFace().getModel(), useStrategy, relativeDist, true); this.hdVisitor = new HausdorffDistance(getPrimaryDrawableFace().getModel(), useStrategy, relativeDist, true);
getSecondaryDrawableFace().getModel().compute(hdVisitor); getSecondaryDrawableFace().getModel().compute(hdVisitor);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
<configuration> <configuration>
<useOSGiDependencies>true</useOSGiDependencies> <useOSGiDependencies>true</useOSGiDependencies>
<publicPackages> <!-- expose API/packages to other modules --> <publicPackages> <!-- expose API/packages to other modules -->
<publicPackage>cz.fidentis.analyst.*</publicPackage>
<publicPackage>cz.fidentis.analyst.mesh.core.*</publicPackage> <publicPackage>cz.fidentis.analyst.mesh.core.*</publicPackage>
<publicPackage>cz.fidentis.analyst.mesh.io.*</publicPackage> <publicPackage>cz.fidentis.analyst.mesh.io.*</publicPackage>
<publicPackage>cz.fidentis.analyst.mesh.*</publicPackage> <publicPackage>cz.fidentis.analyst.mesh.*</publicPackage>
......
package cz.fidentis.analyst;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.logging.Level;
/**
* A logging class that can be used from anywhere to display debugging or other
* messages.
* <p>
* Messages are printed into the standard output unless the {@link #reader()}
* method is called. Then the messages are redirected to the returned {@code BufferedReader}.
* </p>
* <p>
* The implementation supposes that the caller of the {@link #reader()} method
* (or other object} will read the messages from the {@code BufferedReader} forever.
* Otherwise, the program can freeze due to the full buffer.
* </p>
* <p>
* FIDENTIS application automatically redirects logged messages to the output window.
* </p>
* <p>
* <b>Usage:</b>
* <ul>
* <li>To print a message, use {@code Logger.print("message")}. A timestamp is added automatically.</li>
* <li>To print message together with duration, call {@code Logger log = Logger.measureTime();},
* then call the measured operations and finally call {@code log.printDuration("message")}.
* a timestamp and measured duration are added to the log message automatically.</li>
* </ul>
* </p>
*
* @author Radek Oslejsek
*/
public final class Logger {
private static PrintStream out = System.out;
private static BufferedReader in;
private long lastTime = System.currentTimeMillis();
private Logger() {
}
/**
* Redirects logs from standard output to the {@code BufferedReader}.
*
* @return {@code BufferedReader} to which the logs are redirected.
*/
public static BufferedReader reader() {
if (in == null) {
PipedOutputStream pOut = new PipedOutputStream();
out = new PrintStream(pOut);
try {
in = new BufferedReader(new InputStreamReader(new PipedInputStream(pOut)));
} catch (IOException ex) {
java.util.logging.Logger.getLogger(Logger.class.getName()).log(Level.SEVERE, null, ex);
}
}
return in;
}
/**
* Prints a message. The log time added automatically.
*
* @param msg Message to be logged
*/
public static void print(String msg) {
String outMsg =
new SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())
+ " [duration unknown]: "
+ msg.trim();
out.println(outMsg);
}
/**
* Starts measuring of some operation.
* Call {@link #printDuration(java.lang.String)} on returned object
* to print the measured duration.
*
* @return An object used to print measured duration and message
*/
public static Logger measureTime() {
Logger ret = new Logger();
ret.lastTime = System.currentTimeMillis();
return ret;
}
/**
* Prints the message about an operation and the duration of the operation.
* The duration is computed as the difference between current system time and
* the time of calling {@link #measureTime()}. The time difference is measured in
* milliseconds and printed as [+mm:ss.SSS] where mm=minutes, ss=seconds,
* and SSS=milliseconds.
*
* @param msg Message to be printed
*/
public void printDuration(String msg) {
Duration duration = Duration.ofMillis(System.currentTimeMillis() - lastTime);
String outMsg =
new SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())
+ " [duration "
+ String.format(
"%02d:%02d.%03d",
duration.toMinutes(),
duration.toSecondsPart(),
duration.toMillisPart())
+ "]: "
+ msg.trim();
out.println(outMsg);
}
}
...@@ -19,7 +19,7 @@ public class FeaturePointCsvExporter { ...@@ -19,7 +19,7 @@ public class FeaturePointCsvExporter {
/** /**
* Exports a file to set location in csv format <br> * Exports a file to set location in csv format <br>
* File is located and named as {@param objectName}_landmarks.csv * File is located and named as {@code objectName}_landmarks.csv
* *
* @param featurePointList * @param featurePointList
* @param objectName * @param objectName
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment