Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I'm new in java and wanted to add a TextArea on my JavaFX program and get the console messages displayed on it. Exactly like what you get when you start a jar file on white CMD (Exceptions, prints and etc...).
You can create your own implementation of OutputStream to do it:
public class TextInputForwardingOutputStream extends OutputStream {
private final TextInputControl control;
private final Charset charset;
public TextInputForwardingOutputStream(TextInputControl control) {
this(control, Charset.defaultCharset());
}
public TextInputForwardingOutputStream(TextInputControl control, Charset charset) {
this.control = control;
this.charset = charset;
}
#Override
public void write(int b) throws IOException {
write(new byte[]{(byte) b});
}
#Override
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
#Override
public void write(byte[] b, int off, int len) throws IOException {
final String str = new String(b, off, len, this.charset);
Platform.runLater(() -> this.control.appendText(str));
}
}
and then forward the output to that OutputStream:
final TextArea myTextArea = new TextArea();
System.setOut(new PrintStream(new TextInputForwardingOutputStream(myTextArea)));
System.setErr(new PrintStream(new TextInputForwardingOutputStream(myTextArea)));
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 days ago.
Improve this question
public class LoggerDateFormatterTest {
SSLPrintStream sslStream;
static String year = "(\\|\\d\\d\\d\\d-\\d\\d-\\d\\d";
static String hour = "\\s\\d\\d:\\d\\d:\\d\\d\\.\\d\\d\\d\\s";
static String zone = "([A-Za-z]+([\\+\\-][0-2]?[0-9](\\:[0-5]?[0-9]))?))";
static Pattern pattern;
Matcher matcher;
#BeforeTest
public void setUp() {
sslStream = new SSLPrintStream(System.err);
System.setErr(sslStream);
String format = year + hour + zone;
pattern = Pattern.compile(format);
}
#Test
public void testDateFormat() {
SSLLogger.info("logging");
System.out.println("The value is: " + sslStream.bos.toString());
matcher = pattern.matcher(sslStream.bos.toString());
if (matcher.find()) {
out.println("Test Passed with value :" + matcher.group());
}
else {
fail("Test failed wrong SSL DateFormat");
}
}
public static class SSLPrintStream extends PrintStream {
public ByteArrayOutputStream bos; // Stream that accumulates System.err
public SSLPrintStream(OutputStream out) {
super(out);
bos = new ByteArrayOutputStream();
}
#Override
public void write(int b) {
super.write(b);
bos.write(b);
}
#Override
public void write(byte[] buf, int off, int len) {
super.write(buf, off, len);
bos.write(buf, off, len);
}
#Override
public void write(byte[] buf) throws IOException {
super.write(buf);
bos.write(buf);
}
#Override
public void writeBytes(byte[] buf) {
super.writeBytes(buf);
bos.writeBytes(buf);
}
}
}
I am getting java.lang.AssertionError: Test failed wrong SSL DateFormat. How can I correct this? I am using Pattern Class - Defines a pattern (to be used in a search)
and Matcher Class - Used to search for the pattern.
I have a BufferedWriter as shown below:
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new GZIPOutputStream( hdfs.create(filepath, true ))));
String line = "text";
writer.write(line);
I want to find out the bytes written to the file with out querying file like
hdfs = FileSystem.get( new URI( "hdfs://localhost:8020" ), configuration );
filepath = new Path("path");
hdfs.getFileStatus(filepath).getLen();
as it will add overhead and I don't want that.
Also I cant do this:
line.getBytes().length;
As it give size before compression.
You can use the CountingOutputStream from Apache commons IO library.
Place it between the GZIPOutputStream and the file Outputstream (hdfs.create(..)).
After writing the content to the file you can read the number of written bytes from the CountingOutputStream instance.
If this isn't too late and you are using 1.7+ and you don't wan't to pull in an entire library like Guava or Commons-IO, you can just extend the GZIPOutputStream and obtain the data from the associated Deflater like so:
public class MyGZIPOutputStream extends GZIPOutputStream {
public MyGZIPOutputStream(OutputStream out) throws IOException {
super(out);
}
public long getBytesRead() {
return def.getBytesRead();
}
public long getBytesWritten() {
return def.getBytesWritten();
}
public void setLevel(int level) {
def.setLevel(level);
}
}
You can make you own descendant of OutputStream and count how many time write method was invoked
This is similar to the response by Olaseni, but I moved the counting into the BufferedOutputStream rather than the GZIPOutputStream, and this is more robust, since def.getBytesRead() in Olaseni's answer is not available after the stream has been closed.
With the implementation below, you can supply your own AtomicLong to the constructor so that you can assign the CountingBufferedOutputStream in a try-with-resources block, but still retrieve the count after the block has exited (i.e. after the file is closed).
public static class CountingBufferedOutputStream extends BufferedOutputStream {
private final AtomicLong bytesWritten;
public CountingBufferedOutputStream(OutputStream out) throws IOException {
super(out);
this.bytesWritten = new AtomicLong();
}
public CountingBufferedOutputStream(OutputStream out, int bufSize) throws IOException {
super(out, bufSize);
this.bytesWritten = new AtomicLong();
}
public CountingBufferedOutputStream(OutputStream out, int bufSize, AtomicLong bytesWritten)
throws IOException {
super(out, bufSize);
this.bytesWritten = bytesWritten;
}
#Override
public void write(byte[] b) throws IOException {
super.write(b);
bytesWritten.addAndGet(b.length);
}
#Override
public void write(byte[] b, int off, int len) throws IOException {
super.write(b, off, len);
bytesWritten.addAndGet(len);
}
#Override
public synchronized void write(int b) throws IOException {
super.write(b);
bytesWritten.incrementAndGet();
}
public long getBytesWritten() {
return bytesWritten.get();
}
}
I apologize for not being able to think of a more descriptive title.
I have managed to redirect the system.out to a new ListView via my own OutputStream class Console:
public class Console extends OutputStream {
private ListView<String> output;
public Console(ListView<String> output) {
this.output = output;
}
private void addText(String str) {
Platform.runLater( () -> output.getItems().add(str) );
}
#Override
public void write(int b) throws IOException {
addText(String.valueOf((char) b));
}
#Override
public void write(byte[] b, int off, int len) throws IOException {
addText(new String(b, off, len));
}
#Override
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
}
Here, I create the console in my controller class. output is the name of the
ListView in my FXML:
private void buildConsole() {
Console console = new Console(output);
PrintStream ps = new PrintStream(console, true);
System.setOut(ps);
System.setErr(ps);
}
Here is where I am testing the output with an event handler that prints the tile coordinates over which my mouse is hovering:
tile.setOnMouseEntered(e -> {
tile.setFill(hoverColor);
showConnections(tile);
gridController.getCoordinateLabel().setText(tile.getVertex().toString());
System.out.print("Tile " + tile.getVertex().toString() + " selected.");
});
Notice that I am using System.out.print() and not println(). This is the output:
If I were to use println():
My ideal behavior is:
system.out.print() - text to be added to the same line.
system.out.println() - text added to the next cell.
Since you are looking for behavior that corresponds to a system or IDE console, that corresponds, in part, to splitting the output into logical units (i.e. "lines") at newline characters. That would happen automatically if you just collected whatever is written and appended it to a text area, so I would encourage you to try that and see. Even if it turns out to be less efficient, it may still be plenty efficient for your purposes.
If you want to proceed with the ListView, however, then your Console class needs to internally buffer the data written to it, scan for newlines, and break up the output into cells at newlines. It create a new cell only when it sees a newline, and in that case include all the buffered text up to, but not including that newline.
Update:
A ByteArrayOutputStream would make a fine buffer. Something like this, for example:
public class Console extends OutputStream {
private ListView<String> output;
private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
public Console(ListView<String> output) {
this.output = output;
}
private void addText() throws IOException {
String text = buffer.toString("UTF-8");
buffer.reset();
Platform.runLater( () -> output.getItems().add(text) );
}
#Override
public void write(int b) throws IOException {
if (b == '\n') {
addText();
} else {
buffer.write(b);
}
}
#Override
public void write(byte[] b, int off, int len) throws IOException {
int bound = off + len;
for (int i = off; i < bound; i++) {
if (b[i] == '\n') {
buffer.write(b, off, i - off);
addText();
off = i + 1;
}
}
assert(off <= bound);
buffer.write(b, off, bound - off);
}
#Override
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
#Override
public void flush() throws IOException {
// outputs all currently buffered data as a new cell, without receiving
// a newline as otherwise is required for that
addText();
}
#Override
public void close() throws IOException {
flush();
buffer.close();
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
This piece of Java code is hard to understand. How does this DirExplorer get created? Class DirExplorer link is https://github.com/ftomassetti/analyze-java-code-examples/blob/master/src/main/java/me/tomassetti/support/DirExplorer.java
Cheers,
Code is below:
new DirExplorer((level, path, file) -> path.endsWith(".java"), (level, path, file) -> {
System.out.println(path);
System.out.println(Strings.repeat("=", path.length()));
try {
new VoidVisitorAdapter<Object>() {
#Override
public void visit(ClassOrInterfaceDeclaration n, Object arg) {
super.visit(n, arg);
System.out.println(" * " + n.getName());
}
}.visit(JavaParser.parse(file), null);
System.out.println(); // empty line
} catch (ParseException | IOException e) {
new RuntimeException(e);
}
}).explore(projectDir);
Let's refactor the code to the old-style for easier understanding:
Filter filter = new Filter() {
#Override
public boolean interested(int level, String path, File file) {
return path.endsWith(".java");
}
};
FileHandler fileHandler = new FileHandler() {
#Override
public void handle(int level, String path, File file) {
// Your long implementation for FileHandler
}
};
new DirExplorer(filter, fileHandler).explore(projectDir);
The variable filter is an instance of an anonymous class implementing interface Filter, the interface Filter has only one method so in Java 8 it's a functional interface, and the initialisation code above can be shortened by lambda expression in Java 8 to:
Filter filter = (level, path, file) -> path.endsWith(".java");
FileHandler fileHandler = (level, path, file) -> {
// Your implementation for FileHandler
};
new DirExplorer(filter, fileHandler).explore(projectDir);
And further more, you could inline both variables, which leads the code to be:
new DirExplorer((level, path, file) -> path.endsWith(".java"), (level1, path1, file1) -> {
// Your implementation for FileHandler
}).explore(projectDir);
When it's hard to read I break it into smaller, more readable pieces.
Is this easier to understand ?
Filter filter = (level, path, file) -> path.endsWith(".java");
FileHandler fileHandler = (level, path, file) -> {
System.out.println(path);
System.out.println(Strings.repeat("=", path.length()));
try {
new VoidVisitorAdapter<Object>() {
#Override
public void visit(ClassOrInterfaceDeclaration n, Object arg) {
super.visit(n, arg);
System.out.println(" * " + n.getName());
}
}.visit(JavaParser.parse(file), null);
System.out.println(); // empty line
} catch (ParseException | IOException e) {
new RuntimeException(e);
}
};
new DirExplorer(filter, fileHandler).explore(projectDir);
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am making a program where a server offers a quiz to any number of clients. I have to make this using sockets, so I am trying to solve this by making multiple threads with socket objects in my server class, each socket maintaining the connection to one client.
This was working fine until I did some refactoring, after which I discovered through debugging that information between client and server was being sent in the right order by sheer luck.
Here is the code for my client threads. It's an inner class of my Server class and the questionList is an attribute thereof.
private class ClientThread implements AutoCloseable, Runnable
{
private Socket clientConnection;
private DataOutputStream output;
private DataInputStream input;
public ClientThread(Socket clientConnection) throws IOException
{
this.clientConnection = clientConnection;
output = new DataOutputStream(clientConnection.getOutputStream());
output.flush();
input = new DataInputStream(clientConnection.getInputStream());
}
public void sendQuestion() throws IOException
{
if (input.available() > 0) if (input.readBoolean())
{
Question question = questionList.get((int) (Math.random() * questionList.size()));
sendQuestionInfo(question);
}
}
private void sendQuestionInfo(Question question) throws IOException
{
sendInfo(question.getAuthor());
sendInfo(question.getTitle());
}
private void sendInfo(String info) throws IOException
{
output.writeUTF(info);
output.flush();
}
#Override
public void run()
{
try
{
sendQuestion();
}
catch (IOException e)
{
e.printStackTrace();
}
}
#Override
public void close() {...}
}
And here is the relevant code from my Client class:
public class QuizClient implements AutoCloseable
{
private Socket serverConnection;
private DataOutputStream output;
private DataInputStream input;
public QuizClient(String serverAdress, int portNumber) throws IOException
{
serverConnection = new Socket(serverAdress, portNumber);
output = new DataOutputStream(serverConnection.getOutputStream());
output.flush();
input = new DataInputStream(serverConnection.getInputStream());
}
public void getQuiz()
{...}
private void playQuiz(boolean firstRun, Scanner scanner) throws IOException
{...}
private boolean playQuizTurn(Scanner scanner) throws IOException
{...}
private boolean isFirstRun()
{...}
private void askQuestion(Scanner scanner) throws IOException
{
output.writeBoolean(true);
output.flush();
Question question = getQuestion();
question.quizMe(scanner);
}
private Question getQuestion() throws IOException
{
String author = input.readUTF();
String title = input.readUTF();
return new Question(author, title);
}
#Override
public void close() throws IOException
{...}
}
The intended order of execution is askQuestion() -> sendQuestion() -> getQuestion(), but with the current code it insteads runs like sendQuestion() -> askQuestion() -> getQuestion(), and the program ends up being unresponsive.
How can I get this under control?
Your server's ClientThread.sendQuestion() method exits silently if input.available() is 0 - that is, if the "true" has not yet been received from the client - which will often be the case with a newly established client. Try having it wait patiently until there is data available, and see if you get any further.