001package jmri.jmrix.can.cbus.swing.console; 002 003import java.awt.Color; 004import java.awt.Desktop; 005import java.io.File; 006import java.io.FileNotFoundException; 007import java.io.FileOutputStream; 008import java.io.IOException; 009import java.io.PrintStream; 010import javax.swing.*; 011import jmri.util.FileUtil; 012import jmri.util.swing.JmriJOptionPane; 013 014/** 015 * Pane for CBUS Console Logging to File Options 016 * 017 * @author Andrew Crosland Copyright (C) 2008 018 * @author Steve Young Copyright (C) 2018 019 */ 020public class CbusConsoleLoggingPane extends javax.swing.JPanel { 021 022 private final CbusConsolePane _mainPane; 023 private final JFileChooser logFileChooser; 024 private final JToggleButton startStopLogButton; 025 private final JButton openLogFileButton; 026 private final JButton openFileChooserButton; 027 private final JTextField entryField; 028 private final JButton logenterButton; 029 030 // @SuppressFBWarnings(value = "IS2_INCONSISTENT_SYNC", justification = "separately interlocked") 031 private PrintStream logStream; 032 033 public CbusConsoleLoggingPane(CbusConsolePane mainPane){ 034 super(); 035 _mainPane = mainPane; 036 // set file chooser to a default 037 logFileChooser = new jmri.util.swing.JmriJFileChooser(FileUtil.getUserFilesPath()); 038 logFileChooser.setSelectedFile(new File(FileUtil.getUserFilesPath()+"monitorLog.txt")); 039 040 startStopLogButton = new JToggleButton(); 041 openLogFileButton = new JButton(); 042 openFileChooserButton = new JButton(); 043 entryField = new JTextField(); 044 logenterButton = new JButton(); 045 setupPane(); 046 047 } 048 049 private void setupPane() { 050 051 setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); 052 setBorder(BorderFactory.createTitledBorder( 053 BorderFactory.createEtchedBorder(), Bundle.getMessage("Logging"))); 054 055 setButtonToolTips(); 056 057 add(startStopLogButton); 058 add(openFileChooserButton); 059 add(openLogFileButton); 060 add(logenterButton); 061 add(entryField); 062 063 addListeners(); 064 065 } 066 067 private void setSelectFileToolTip() { 068 069 openFileChooserButton.setToolTipText(logFileChooser.getSelectedFile().getPath()); 070 071 072 } 073 074 private void addListeners() { 075 076 startStopLogButton.addActionListener((java.awt.event.ActionEvent e) -> { 077 078 openFileChooserButton.setEnabled(!startStopLogButton.isSelected()); 079 080 if (startStopLogButton.isSelected()){ 081 startLogButtonActionPerformed(e); 082 } 083 else { 084 stopLogButtonActionPerformed(e); 085 } 086 087 updateStartStopButtonText(); 088 089 }); 090 091 openFileChooserButton.addActionListener(this::openFileChooserButtonActionPerformed); 092 093 openLogFileButton.addActionListener((java.awt.event.ActionEvent e) -> { 094 try { 095 openLogFileActionPerformed(e); 096 } catch (IOException ex) { 097 log.error("log file open exception", ex); 098 } 099 }); 100 101 logenterButton.addActionListener(this::textToLogButtonActionPerformed); 102 entryField.addActionListener(this::textToLogButtonActionPerformed); 103 104 updateStartStopButtonText(); 105 106 } 107 108 private void setButtonToolTips() { 109 110 logenterButton.setText(Bundle.getMessage("ButtonAddMessage")); 111 logenterButton.setToolTipText(Bundle.getMessage("TooltipAddMessage")); 112 113 openFileChooserButton.setText(Bundle.getMessage("ButtonChooseLogFile")); 114 setSelectFileToolTip(); 115 116 openLogFileButton.setText(Bundle.getMessage("OpenLogFile")); 117 openLogFileButton.setToolTipText(Bundle.getMessage("OpenLogFileTip")); 118 119 entryField.setToolTipText(Bundle.getMessage("EntryAddtoLogTip")); 120 121 } 122 123 private void updateStartStopButtonText(){ 124 125 if (startStopLogButton.isSelected()){ 126 127 startStopLogButton.setText(Bundle.getMessage("ButtonStopLogging")); 128 startStopLogButton.setToolTipText(Bundle.getMessage("TooltipStopLogging")); 129 startStopLogButton.setForeground(Color.red); 130 131 } 132 else { 133 134 startStopLogButton.setText(Bundle.getMessage("ButtonStartLogging")); 135 startStopLogButton.setToolTipText(Bundle.getMessage("TooltipStartLogging") + " " + 136 Bundle.getMessage("ButtonStartLogTipExtra")); 137 startStopLogButton.setForeground(new JToggleButton().getForeground()); 138 139 } 140 141 } 142 143 private void startLogButtonActionPerformed(java.awt.event.ActionEvent e) { 144 // start logging by creating the stream 145 if (logStream == null) { // successive clicks don't restart the file 146 // start logging 147 try { 148 logStream = new PrintStream(new FileOutputStream(logFileChooser.getSelectedFile())); 149 } catch (FileNotFoundException ex) { 150 log.error("exception", ex); 151 } 152 } 153 } 154 155 private void stopLogButtonActionPerformed(java.awt.event.ActionEvent e) { 156 // stop logging by removing the stream 157 if (logStream != null) { 158 logStream.flush(); 159 logStream.close(); 160 } 161 logStream = null; 162 } 163 164 private void openFileChooserButtonActionPerformed(java.awt.event.ActionEvent e) { 165 // start at current file, show dialog 166 int retVal = logFileChooser.showSaveDialog(this); 167 168 // handle selection or cancel 169 if (retVal == JFileChooser.APPROVE_OPTION) { 170 boolean loggingNow = (logStream != null); 171 stopLogButtonActionPerformed(e); // stop before changing file 172 //File file = logFileChooser.getSelectedFile(); 173 // if we were currently logging, start the new file 174 if (loggingNow) { 175 startLogButtonActionPerformed(e); 176 } 177 } 178 setSelectFileToolTip(); 179 } 180 181 private void openLogFileActionPerformed(java.awt.event.ActionEvent e) throws IOException { 182 // start at current file, show dialog 183 Desktop desktop = Desktop.getDesktop(); 184 File dirToOpen; 185 186 try { 187 dirToOpen = logFileChooser.getSelectedFile(); 188 desktop.open(dirToOpen); 189 } catch (IllegalArgumentException iae) { 190 JmriJOptionPane.showMessageDialog(_mainPane, 191 (Bundle.getMessage("NoOpenLogFile")), Bundle.getMessage("WarningTitle"), 192 JmriJOptionPane.ERROR_MESSAGE); 193 } 194 195 } 196 197 private void textToLogButtonActionPerformed(java.awt.event.ActionEvent e) { 198 _mainPane.nextLine(entryField.getText() + "\n", entryField.getText() + "\n", -1); 199 } 200 201 private final String newline = System.getProperty("line.separator"); 202 203 protected void sendLogToFile( String sbCbus ){ 204 if (logStream != null) { 205 String logLine = sbCbus; 206 if (!newline.equals("\n")) { 207 // have to massage the line-ends 208 StringBuilder out = new StringBuilder(sbCbus.length() + 10); // arbitrary guess at space 209 for (int j = 0; j < sbCbus.length(); j++) { 210 if (sbCbus.charAt(j) == '\n') { 211 out.append(newline); 212 } else { 213 out.append(sbCbus.charAt(j)); 214 } 215 } 216 logLine = new String(out); 217 } 218 logStream.print(logLine); 219 } 220 } 221 222 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CbusConsoleLoggingPane.class); 223 224}