/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.jmeter.gui;
import java.awt.BorderLayout;
import java.awt.Insets;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.Timer;
import org.apache.commons.collections.Buffer;
import org.apache.commons.collections.buffer.CircularFifoBuffer;
import org.apache.commons.collections.buffer.UnboundedFifoBuffer;
import org.apache.jmeter.gui.logging.GuiLogEventListener;
import org.apache.jmeter.gui.logging.LogEventObject;
import org.apache.jmeter.gui.util.JSyntaxTextArea;
import org.apache.jmeter.gui.util.JTextScrollPane;
import org.apache.jmeter.util.JMeterUtils;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
/**
* Panel that shows log events
*/
public class LoggerPanel extends JPanel implements GuiLogEventListener {
private static final long serialVersionUID = 6911128494402594429L;
private final JTextArea textArea;
// Limit length of log content
// 0 means unlimited
private static final int LOGGER_PANEL_MAX_LINES =
JMeterUtils.getPropDefault("jmeter.loggerpanel.maxlength", 1000); // $NON-NLS-1$
// Make panel handle event even if closed
private static final boolean LOGGER_PANEL_RECEIVE_WHEN_CLOSED =
JMeterUtils.getPropDefault("jmeter.loggerpanel.enable_when_closed", true); // $NON-NLS-1$
private static final int LOGGER_PANEL_REFRESH_PERIOD =
JMeterUtils.getPropDefault("jmeter.gui.refresh_period", 500); // $NON-NLS-1$
private final Buffer events;
private volatile boolean logChanged = false;
/**
* Pane for display JMeter log file
*/
public LoggerPanel() {
if (LOGGER_PANEL_MAX_LINES > 0) {
events =
new CircularFifoBuffer(LOGGER_PANEL_MAX_LINES);
} else {
events = new UnboundedFifoBuffer();
}
textArea = init();
}
private JTextArea init() { // WARNING: called from ctor so must not be overridden (i.e. must be private or final)
this.setLayout(new BorderLayout());
final JScrollPane areaScrollPane;
final JTextArea jTextArea;
if (JMeterUtils.getPropDefault("loggerpanel.usejsyntaxtext", true)) {
// JSyntax Text Area
JSyntaxTextArea jSyntaxTextArea = JSyntaxTextArea.getInstance(15, 80, true);
jSyntaxTextArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_NONE);
jSyntaxTextArea.setCodeFoldingEnabled(false);
jSyntaxTextArea.setAntiAliasingEnabled(false);
jSyntaxTextArea.setEditable(false);
jSyntaxTextArea.setLineWrap(false);
jSyntaxTextArea.setLanguage("text");
jSyntaxTextArea.setMargin(new Insets(2, 2, 2, 2)); // space between borders and text
areaScrollPane = JTextScrollPane.getInstance(jSyntaxTextArea);
jTextArea = jSyntaxTextArea;
} else {
// Plain text area
jTextArea = new JTextArea(15, 80);
areaScrollPane = new JScrollPane(jTextArea);
}
areaScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
areaScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
this.add(areaScrollPane, BorderLayout.CENTER);
initWorker();
return jTextArea;
}
/* (non-Javadoc)
* @see org.apache.jmeter.gui.logging.GuiLogEventListener#processLogEvent(org.apache.jmeter.gui.logging.LogEventObject)
*/
@SuppressWarnings("unchecked")
@Override
public void processLogEvent(final LogEventObject logEventObject) {
if(!LOGGER_PANEL_RECEIVE_WHEN_CLOSED && !GuiPackage.getInstance().getMenuItemLoggerPanel().getModel().isSelected()) {
return;
}
String logMessage = logEventObject.toString();
synchronized (events) {
events.add(logMessage);
}
logChanged = true;
}
private void initWorker() {
Timer timer = new Timer(
LOGGER_PANEL_REFRESH_PERIOD,
e -> updateLogEntries());
timer.start();
}
private void updateLogEntries() {
if (!logChanged) {
return;
}
logChanged = false;
StringBuilder builder = new StringBuilder();
synchronized (events) {
for (Object line: events) {
builder.append((String) line);
}
}
String logText = builder.toString();
synchronized (textArea) {
if (LOGGER_PANEL_MAX_LINES > 0) {
textArea.setText(logText);
} else {
textArea.append(logText);
}
textArea.setCaretPosition(textArea.getText().length());
}
}
/**
* Clear panel content
*/
public void clear() {
synchronized (events) {
events.clear();
}
logChanged = true;
}
}