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