我有以下问题。当我输入内容并在控制台中打印一条消息时,它将显示如下:Image
我想让输入始终在底部。
这是我的代码: CloudLogger:
package net.kolania.cloud.cloudserver.logging;
import jline.UnsupportedTerminal;
import jline.console.ConsoleReader;
import lombok.Getter;
import lombok.Setter;
import net.kolania.cloud.cloudserver.CloudServer;
import net.kolania.cloud.cloudserver.logging.async.AsyncPrintStream;
import net.kolania.cloud.cloudserver.logging.util.FileFormatter;
import net.kolania.cloud.cloudserver.logging.util.LoggingFormatter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.logging.*;
/**
* A logger class with file logging.
*/
@Getter
public class CloudLogger {
private final Logger logger;
private final ConsoleReader consoleReader;
@Setter
private LoggingFormatter loggingFormatter;
@Setter
private FileFormatter fileFormatter;
/**
* Constructor of the {@link} CloudLogger class.
*/
public CloudLogger() throws IOException {
logger = Logger.getLogger("CloudServerLogger");
(consoleReader = new ConsoleReader(System.in, System.out, new UnsupportedTerminal())).setExpandEvents(false);
LoggingHandler loggingHandler = new LoggingHandler();
loggingFormatter = new LoggingFormatter();
fileFormatter = new FileFormatter();
logger.setUseParentHandlers(false);
logger.setLevel(Level.ALL);
File folder = new File("logs/");
if (!folder.exists()) {
folder.mkdir();
}
File latest = new File("logs/latest.log");
if (latest.exists()) {
latest.renameTo(new File("logs/" + System.currentTimeMillis() + ".log"));
}
FileHandler fileHandler = null;
try {
fileHandler = new FileHandler("logs/latest.log");
} catch (SecurityException | IOException exception) {
exception.printStackTrace();
}
loggingHandler.setFormatter(loggingFormatter);
loggingHandler.setLevel(Level.ALL);
logger.addHandler(loggingHandler);
fileHandler.setFormatter(fileFormatter);
fileHandler.setLevel(Level.ALL);
logger.addHandler(fileHandler);
System.setOut(new AsyncPrintStream(new LoggingOutputStream(Level.INFO)));
System.setErr(new AsyncPrintStream(new LoggingOutputStream(Level.SEVERE)));
}
/**
* Logs an information.
*
* @param message Message that has to be logged. See {@link String}
*/
public void info(String message) {
logger.info(message);
}
/**
* Logs an debug-message.
*
* @param message Debug-Message that has to be logged. See {@link String}
*/
public void debug(String message) {
if (CloudServer.getInstance().isDebug()) logger.config(message);
}
/**
* Logs an warning.
*
* @param message Warn-Message that has to be logged. See {@link String}
*/
public void warning(String message) {
logger.warning(message);
}
/**
* Logs an error.
*
* @param message Error-Message that has to be logged. See {@link String}
*/
public void error(String message) {
logger.severe(message);
}
/**
* {@link LoggingHandler} class
*/
private class LoggingHandler extends Handler {
public LoggingHandler() {
try {
this.setEncoding(StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException ex) {
}
}
@Override
public void publish(final LogRecord record) {
if (this.isLoggable(record)) {
try {
consoleReader.print(loggingFormatter.format(record));
consoleReader.println();
consoleReader.flush();
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
@Override
public void flush() {
}
@Override
public void close() throws SecurityException {
}
}
/**
* {@link LoggingOutputStream} class
*/
private class LoggingOutputStream extends ByteArrayOutputStream {
private final Level level;
public LoggingOutputStream(final Level level) {
this.level = level;
}
@Override
public void flush() throws IOException {
final String contents = this.toString(StandardCharsets.UTF_8.name());
super.reset();
if (!contents.isEmpty() && !contents.equals(System.lineSeparator())) {
CloudLogger.this.getLogger().logp(this.level, "", "", contents);
}
}
}
}
控制台:
package net.kolania.cloud.cloudserver.console;
import jline.console.ConsoleReader;
import jline.console.completer.CandidateListCompletionHandler;
import lombok.Data;
import net.kolania.cloud.cloudserver.CloudServer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Data
public class Console extends Thread {
private ConsoleReader consoleReader;
private List<Command> commands;
public Console(ConsoleReader consoleReader) {
this.consoleReader = consoleReader;
consoleReader.setPrompt("");
consoleReader.setCompletionHandler(new CandidateListCompletionHandler());
commands = new ArrayList<>();
}
@Override
public void run() {
String line;
String[] split = null;
try {
while (!isInterrupted() && (line = consoleReader.readLine()) != null) {
console(line, split);
line = null;
split = null;
}
} catch (IOException exception) {
exception.printStackTrace();
}
}
private void console(String line, String[] split) {
if (line.contains(" ")) {
split = line.split(" ");
for (Command command : commands) {
if (command.getCommand().equalsIgnoreCase(split[0]) || command.isAlias(split[0])) {
if (split.length != 1) {
if (command.handleSubCommand(split[1], Arrays.copyOfRange(split, 2, split.length))) {
return;
}
}
command.handle(Arrays.copyOfRange(split, 1, split.length));
return;
}
}
CloudServer.getLogger().info("This command does not exist, type 'help' for a list of all available commands.");
} else {
for (Command command : commands) {
if (command.getCommand().equalsIgnoreCase(line)) {
command.handle(null);
return;
}
}
CloudServer.getLogger().info("This command does not exist, type 'help' for a list of all available commands.");
}
}
public void addCommand(Command command) {
commands.add(command);
consoleReader.addCompleter(command.getStringsCompleter());
}
public void removeCommand(Command command) {
commands.remove(command);
consoleReader.removeCompleter(command.getStringsCompleter());
}
public boolean isCommandExists(Command command) {
return commands.contains(command);
}
public List<Command> getCommands() {
return commands;
}
}
如果您需要更多代码,请在此处发布。 我希望你能帮助我或给我另一种解决方案。
此致 Skyleiger
P.S。抱歉我的英语不好,但我是德国人。我希望你能理解一切。