我在Windows上使用Eclipse IDE(Oxygen)学习Java(SE 8)。我之前做了一些“爱好”编程,但这是我在该主题中的第一个正式课程。我希望能够在普通控制台(System.out.println)中打印分配所需的输出,并同时将信息正在发生的内容文本打印到另一个控制台。
在伪代码中,我想要的是:
printToConsole1(“正常程序输出。”); printToConsole2(“幕后信息”。);
我可以在Java中做这样的事情吗?
答案 0 :(得分:1)
使用Logback或Log4j2之类的日志记录框架,您可以在特定日志记录级别或从不同的记录程序将消息写入两个单独的文件。在这种情况下,你可以完成你正在寻找的东西;你会写出" normal"输出到控制台或一个文件,并将幕后信息输出到单独的文件。
如何在应用程序中配置这些 以及 超出Stack Overflow的范围,但我强烈建议您仔细阅读它们。
嘿,没有人说你不能打开两个终端窗口,你知道吗?答案 1 :(得分:0)
您可以打印到标准错误(System.err.println()
),我的IDE(不是Eclipse)将以不同的方式格式化这些行 - 它们显示为红色,使它们很容易找到。
关于摇摆控制台,我没有想到不同的东西。即只是使用Makoto建议的日志框架,然后只使用一个日志处理程序,它将向窗口显示日志行。以下是我创建的一个简短示例。
/**
* A log handler which creates a visible window for logging output.
*
* <p>A WindowHandler is a standard log handler which may be utilized
* in just the same was as any other log handler.</p>
*
* <p>In addition, a convenience static method is provided, WindowHandler.show(),
* which will programmatically install a root handler and display a window,
* allowing debugging output to be easily captured and viewed on screen.</p>
*
* @author Brenden
*/
public class WindowHandler extends java.util.logging.Handler {
// These static globals must be accessed on the EDT only!
private static WindowHandler globalHandler;
private static final ArrayList<WeakReference<WindowHandler>> windowList =
new ArrayList<>();
private JTextArea text;
private JFrame logWindow;
/**
* Returns the window component (usually a JFrame) associated with this
* WindowHandler.
*
* @return The top-level window for this handler.
*/
public Component getWindow() {
return logWindow;
}
/**
* Returns the JTextArea associated with the logging output captured by
* this handler.
*
* @return A JTextArea where logging is displayed.
*/
public JTextArea getTextArea() {
return text;
}
/**
* A list of ALL WindowHandler created so far in the system.
*
* <p>This list is useful for getting a list of windows on screen, for
* example, and then performing some operation on these windows. For
* example, hiding all windows, or closing them, or tiling them on screen
* for easier viewing.</p>
*
* @return An array list of all current window handlers.
*/
public static ArrayList<WindowHandler> getHandlers() {
ArrayList<WindowHandler> retVal = new ArrayList<>();
for( WeakReference<WindowHandler> wr : windowList ) {
WindowHandler h = wr.get();
if( h != null ) retVal.add( h );
}
return retVal;
}
/**
* A convenience method for starting an instance of a WindowHandler.
*
* <p>Call this method at the beginning of your program. After calling
* this method, all debugging output will be captured by the
* WindowHandler. Note that individual loggers still have their respective
* log levels. WindowHandler is set to Level.ALL by default, but won't
* receive output from loggers that have their own levels set too high
* to capture output.</p>
*/
public static synchronized void show() {
utilEDTWait( () -> {
if( globalHandler == null ) {
Logger root = Logger.getLogger( "" );
root.addHandler( globalHandler = new WindowHandler() );
} else {
globalHandler.getWindow().setVisible( true );
}
} );
}
/**
* Creates a new WindowHandler.
*
* <p>This method creates a new handler, sets its level to ALL, and creates
* the necessary Swing components on the EDT, and displays those components
* as well. After creation, this handler may still be configured as normal
* for any other logging handler.</p>
*/
public WindowHandler() {
utilEDTWait( () -> {
setLevel( Level.ALL );
JFrame frame = new JFrame( "DEBUG" );
text = new JTextArea();
text.setEditable( false );
text.setPreferredSize( new Dimension( 300, 300 ) );
JScrollPane scroll = new JScrollPane( text );
frame.add( scroll );
frame.setDefaultCloseOperation( JFrame.HIDE_ON_CLOSE );
frame.pack();
frame.setLocation( windowList.size()*20, windowList.size()*20 );
frame.setVisible( true );
logWindow = frame;
windowList.add( new WeakReference<>( this ) );
} );
}
@Override
public void publish( LogRecord record ) {
SwingUtilities.invokeLater( () -> {
StringBuilder log = new StringBuilder( text.getText() );
log.append( record.getMessage() );
log.append( " -- " );
log.append( record.getLoggerName() );
log.append( " : " );
log.append( record.getLevel() );
log.append( " // " );
log.append( new Date( record.getMillis() ) );
log.append( "\n" );
text.setText( log.toString() );
} );
}
@Override
public void flush() {
}
@Override
public void close() throws SecurityException {
}
private static void utilEDTWait( Runnable r ) {
if( SwingUtilities.isEventDispatchThread() ) {
r.run();
} else {
try {
SwingUtilities.invokeAndWait( r );
} catch( InterruptedException ex ) {
Thread.currentThread().interrupt();
throw new RuntimeException( ex );
} catch( InvocationTargetException ex ) {
Logger.getLogger( WindowHandler.class.getName() ).log( Level.SEVERE, null, ex );
}
}
}
}
答案 2 :(得分:-1)
获取有关程序运行方式的“逐个播放”信息的最简单方法是在调试模式下运行它。
在Eclipse中,运行 - &gt;调试为 - &gt; Java应用程序。
然而,这可能会导致信息过载,因此您可以考虑添加那些额外的打印语句,以帮助您测试和理解您的代码并在转交作业之前将其注释/暂时删除。通过这种方式,您可以稍后查看该项目以供参考。
至于你最初想要这样做的方式,虽然这样的事情并非毫无疑问是不可能的,但是它会非常耗费工作,并且远远超出了学习制作控制台程序的人的能力。
答案 3 :(得分:-1)
没有。您的Java应用程序具有与任何进程相同的限制:标准输入(System.in
),标准输出(System.out
)和标准错误输出(System.err
),以及常规和错误输出显示在同一控制台中。但是,它们使用不同的颜色显示。通常,您可以使用主boolean
值作为开/关切换来包装一个调用,或者使用某种类型的日志库来使这两种输出更容易区分。
将两者分成自己的控制台会产生一个有趣的功能请求。