001package jmri.jmrit.jython; 002 003import java.awt.BorderLayout; 004import java.awt.Font; 005import java.awt.event.ActionEvent; 006import java.awt.event.ItemEvent; 007import java.awt.event.ItemListener; 008import javax.swing.AbstractAction; 009import javax.swing.JButton; 010import javax.swing.JCheckBox; 011import javax.swing.JFrame; 012import javax.swing.JPanel; 013import javax.swing.JScrollPane; 014import javax.swing.JTextArea; 015import javax.swing.ScrollPaneConstants; 016import javax.swing.event.DocumentEvent; 017import javax.swing.event.DocumentListener; 018import jmri.InstanceManager; 019import jmri.UserPreferencesManager; 020import jmri.script.swing.ScriptOutput; 021import jmri.util.JmriJFrame; 022 023/** 024 * This Action creates a JmriJFrame displaying the thread output log from the 025 * {@link RunJythonScript} class. 026 * 027 * @author Bob Jacobsen Copyright (C) 2004 028 * @author Matthew Harris Copyright (C) 2010 029 */ 030public class JythonWindow extends AbstractAction { 031 032 private JTextArea area; 033 private JFrame f; 034 private JCheckBox autoScroll; 035 private UserPreferencesManager pref; 036 private JButton clearButton; 037 038 public static final String alwaysOnTopCheck = JythonWindow.class.getName() + ".alwaysOnTop"; 039 public static final String alwaysScrollCheck = JythonWindow.class.getName() + ".alwaysScroll"; 040 protected JCheckBox alwaysOnTopCheckBox = new JCheckBox(); 041 042 /** 043 * Constructor just initializes parent class. 044 * 045 * @param name Action name 046 */ 047 public JythonWindow(String name) { 048 super(name); 049 } 050 051 public JythonWindow() { 052 super("Script Output Window"); 053 } 054 055 /** 056 * Invoking this action via an event triggers display of a file dialog. If a 057 * file is selected, it's then invoked as a script. 058 */ 059 @Override 060 public void actionPerformed(ActionEvent e) { 061 pref = InstanceManager.getDefault(UserPreferencesManager.class); 062 063 f = new JmriJFrame(Bundle.getMessage("TitleOutputFrame")); 064 f.getContentPane().add( 065 new JScrollPane( 066 area = new javax.swing.JTextArea(ScriptOutput.getDefault().getOutputArea().getDocument(), null, 12, 50), 067 ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, 068 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED 069 ), BorderLayout.CENTER); 070 071 // Add checkbox to enable/disable auto-scrolling 072 JPanel p = new JPanel(); 073 p.add(clearButton = new JButton(Bundle.getMessage("ButtonClear"))); 074 p.add(autoScroll = new JCheckBox(Bundle.getMessage("CheckBoxAutoScroll"), true)); 075 autoScroll.setSelected(pref.getSimplePreferenceState(alwaysScrollCheck)); 076 alwaysOnTopCheckBox.setText(Bundle.getMessage("WindowAlwaysOnTop")); 077 alwaysOnTopCheckBox.setVisible(true); 078 alwaysOnTopCheckBox.setToolTipText(Bundle.getMessage("WindowAlwaysOnTopToolTip")); 079 alwaysOnTopCheckBox.setSelected(pref.getSimplePreferenceState(alwaysOnTopCheck)); 080 p.add(alwaysOnTopCheckBox); 081 f.setAlwaysOnTop(alwaysOnTopCheckBox.isSelected()); 082 083 autoScroll.addItemListener(new ItemListener() { 084 085 // Reference to the JTextArea of this instantiation 086 JTextArea ta = area; 087 088 @Override 089 public void itemStateChanged(ItemEvent e) { 090 if (e.getStateChange() == ItemEvent.SELECTED) { 091 doAutoScroll(ta, true); 092 pref.setSimplePreferenceState(alwaysScrollCheck, autoScroll.isSelected()); 093 } 094 } 095 }); 096 097 alwaysOnTopCheckBox.addActionListener((ActionEvent ae) -> { 098 f.setAlwaysOnTop(alwaysOnTopCheckBox.isSelected()); 099 pref.setSimplePreferenceState(alwaysOnTopCheck, alwaysOnTopCheckBox.isSelected()); 100 }); 101 102 clearButton.addActionListener((ActionEvent ae) -> { 103 area.setText(""); 104 }); 105 f.getContentPane().add(p, BorderLayout.PAGE_END); 106 107 // set a monospaced font 108 int size = area.getFont().getSize(); 109 area.setFont(new Font("Monospaced", Font.PLAIN, size)); 110 111 // Add document listener to scroll to end when modified 112 area.getDocument().addDocumentListener(new DocumentListener() { 113 114 // References to the JTextArea and JCheckBox 115 // of this instantiation 116 JTextArea ta = area; 117 JCheckBox chk = autoScroll; 118 119 @Override 120 public void insertUpdate(DocumentEvent e) { 121 doAutoScroll(ta, chk.isSelected()); 122 } 123 124 @Override 125 public void removeUpdate(DocumentEvent e) { 126 doAutoScroll(ta, chk.isSelected()); 127 } 128 129 @Override 130 public void changedUpdate(DocumentEvent e) { 131 doAutoScroll(ta, chk.isSelected()); 132 } 133 }); 134 135 // Scroll to end of document 136 doAutoScroll(area, true); 137 138 f.pack(); 139 f.setVisible(true); 140 } 141 142 /** 143 * Method to position caret at end of JTextArea ta when scroll true. 144 * 145 * @param ta Reference to JTextArea 146 * @param scroll True to move to end 147 */ 148 private void doAutoScroll(JTextArea ta, boolean scroll) { 149 if (scroll) { 150 ta.setCaretPosition(ta.getText().length()); 151 } 152 } 153 154 public JFrame getFrame() { 155 return f; 156 } 157 158}