package org.alastairmailer;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ListCellRenderer;
import javax.swing.Timer;
import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
public class IndexLogMsgHandler extends Handler implements ActionListener {
private DefaultListModel records;
private JList recordList;
private JPanel frame;
private IndexBuilder indexingThread;
private Timer timer;
public IndexLogMsgHandler(IndexBuilder indexingThread) {
records = new DefaultListModel();
recordList = new JList(records);
recordList.setCellRenderer(new LogMsgCellRenderer());
recordList.setPrototypeCellValue(new LogRecord(Level.INFO, "A prototype logging message, not too long but long enough"));
frame = buildPanel();
timer = new Timer(100, this);
this.indexingThread = indexingThread;
indexingThread.logger.addHandler(this);
}
public JDialog getDialog(Window parent, boolean modal) {
dialog = new JDialog(parent, modal ? ModalityType.APPLICATION_MODAL : ModalityType.MODELESS);
dialog.add(frame);
dialog.pack();
dialog.setResizable(false);
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
return dialog;
}
JProgressBar progress;
JButton okButton;
JLabel msg;
private JDialog dialog;
private JPanel buildPanel() {
FormLayout layout = new FormLayout("300dlu");
DefaultFormBuilder builder = new DefaultFormBuilder(layout);
builder.setDefaultDialogBorder();
builder.append("Rebuilding the file index...");
builder.nextLine();
progress = new JProgressBar();
progress.setIndeterminate(true);
builder.append(progress);
builder.nextLine();
msg = new JLabel();
builder.append(msg);
builder.nextRow();
builder.appendUnrelatedComponentsGapRow();
builder.append("Messages:");
builder.nextLine();
builder.append(new JScrollPane(recordList));
builder.nextLine();
okButton = new JButton("OK");
okButton.setEnabled(false);
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dialog.setVisible(false);
}
});
builder.append(okButton);
CellConstraints cc = layout.getConstraints(okButton);
cc.hAlign = CellConstraints.RIGHT;
layout.setConstraints(okButton, cc);
builder.nextRow();
builder.appendUnrelatedComponentsGapRow();
return builder.getPanel();
}
@Override
public void close() throws SecurityException {
records.clear();
}
@Override
public void flush() {
}
@Override
public void publish(LogRecord record) {
records.add(0, record);
}
public void actionPerformed(ActionEvent e) {
switch(indexingThread.getStatus()) {
case IndexBuilder.INACTIVE:
break;
case IndexBuilder.OPENING:
msg.setText("Opening index...");
progress.setStringPainted(true);
break;
case IndexBuilder.INDEXING:
if (progress.isIndeterminate()) {
progress.setMinimum(0);
progress.setMaximum(indexingThread.filesToDo());
progress.setIndeterminate(false);
}
int currentFile = indexingThread.filesToDo() - indexingThread.filesRemaining();
progress.setValue(currentFile);
msg.setText("Indexed " + currentFile + " of " + progress.getMaximum() + " files");
break;
case IndexBuilder.WRITING:
msg.setText("Finished indexing, writing index files to disk...");
break;
case IndexBuilder.FINISHED:
msg.setText("Index rebuilt successfully!");
progress.setValue(progress.getMaximum());
okButton.setEnabled(true);
timer.stop();
break;
case IndexBuilder.ERROR:
progress.setValue(progress.getMaximum());
msg.setText("A fatal error occured during indexing");
okButton.setEnabled(true);
timer.stop();
break;
}
}
public void startTimer() {
timer.start();
}
}
class LogMsgCellRenderer implements ListCellRenderer {
private JTextArea labelTemplate = new JTextArea();
private ImageIcon iconTemplate;
private static final ImageIcon
WARN_ICON = new ImageIcon(LuceneSidePanelPlugin.getResourceURL("images/warning.png")),
ERROR_ICON = new ImageIcon(LuceneSidePanelPlugin.getResourceURL("images/error.png")),
INFO_ICON = new ImageIcon(LuceneSidePanelPlugin.getResourceURL("images/info.png"));
public Component getListCellRendererComponent(JList list,
Object value, int index, boolean isSelected,
boolean cellHasFocus) {
LogRecord rec = (LogRecord)value;
labelTemplate.setLineWrap(true);
labelTemplate.setWrapStyleWord(true);
labelTemplate.setText(rec.getMessage());
if (rec.getLevel().equals(Level.INFO)) {
iconTemplate = INFO_ICON;
} else if (rec.getLevel().equals(Level.WARNING)) {
iconTemplate = WARN_ICON;
} else if (rec.getLevel().equals(Level.SEVERE)) {
iconTemplate = ERROR_ICON;
} else {
iconTemplate = null;
}
if (isSelected) {
labelTemplate.setBackground(list.getSelectionBackground());
labelTemplate.setForeground(list.getSelectionForeground());
} else {
labelTemplate.setBackground(list.getBackground());
labelTemplate.setForeground(list.getForeground());
}
labelTemplate.setEnabled(list.isEnabled());
labelTemplate.setFont(list.getFont());
labelTemplate.setOpaque(true);
JPanel panel = new JPanel(new BorderLayout(5, 0));
JLabel iconLabel = new JLabel(iconTemplate);
if (isSelected) {
iconLabel.setBackground(list.getSelectionBackground());
iconLabel.setForeground(list.getSelectionForeground());
} else {
iconLabel.setBackground(list.getBackground());
iconLabel.setForeground(list.getForeground());
}
iconLabel.setOpaque(true);
panel.add(iconLabel, BorderLayout.LINE_START);
panel.add(labelTemplate, BorderLayout.CENTER);
if (isSelected) {
panel.setBackground(list.getSelectionBackground());
panel.setForeground(list.getSelectionForeground());
} else {
panel.setBackground(list.getBackground());
panel.setForeground(list.getForeground());
}
panel.setOpaque(true);
JLabel spacer = new JLabel();
spacer.setPreferredSize(new Dimension(10, 5));
panel.add(spacer, BorderLayout.PAGE_END);
return panel;
}
}