@edu.umd.cs.findbugs.annotations.SuppressFBWarnings( value = "DM_DEFAULT_ENCODING", justification = "Can only be called from the same instance so default encoding OK") private SystemConsole() { // Record current System.out and System.err // so that we can still send to them originalOut = System.out; originalErr = System.err; // Create the console text area console = new JTextArea(); // Setup the console text area console.setRows(20); console.setColumns(120); console.setFont(new Font(fontFamily, fontStyle, fontSize)); console.setEditable(false); setScheme(scheme); setWrapStyle(wrapStyle); this.outputStream = new PrintStream(outStream(STD_OUT), true); this.errorStream = new PrintStream(outStream(STD_ERR), true); // Then redirect to it redirectSystemStreams(); }
/** Layout the console frame */ private void createFrame() { // Use a JmriJFrame to ensure that we fit on the screen frame = new JmriJFrame(Bundle.getMessage("TitleConsole")); pref = jmri.InstanceManager.getDefault(jmri.UserPreferencesManager.class); // Add Help menu (Windows menu automaitically added) frame.addHelpMenu("package.apps.SystemConsole", true); // NOI18N // Grab a reference to the system clipboard final Clipboard clipboard = frame.getToolkit().getSystemClipboard(); // Setup the scroll pane JScrollPane scroll = new JScrollPane(console); frame.add(scroll, BorderLayout.CENTER); // Add button to allow copy to clipboard JPanel p = new JPanel(); JButton copy = new JButton(Bundle.getMessage("ButtonCopyClip")); copy.addActionListener( (ActionEvent event) -> { StringSelection text = new StringSelection(console.getText()); clipboard.setContents(text, text); }); p.add(copy); // Add button to allow console window to be closed JButton close = new JButton(Bundle.getMessage("ButtonClose")); close.addActionListener( (ActionEvent event) -> { frame.setVisible(false); frame.dispose(); }); p.add(close); JButton stackTrace = new JButton(Bundle.getMessage("ButtonStackTrace")); stackTrace.addActionListener( (ActionEvent event) -> { performStackTrace(); }); p.add(stackTrace); // Add checkbox to enable/disable auto-scrolling // Use the inverted SimplePreferenceState to default as enabled p.add( autoScroll = new JCheckBox( Bundle.getMessage("CheckBoxAutoScroll"), !pref.getSimplePreferenceState(alwaysScrollCheck))); autoScroll.addActionListener( (ActionEvent event) -> { doAutoScroll(console, autoScroll.isSelected()); pref.setSimplePreferenceState(alwaysScrollCheck, !autoScroll.isSelected()); }); // Add checkbox to enable/disable always on top p.add( alwaysOnTop = new JCheckBox( Bundle.getMessage("CheckBoxOnTop"), pref.getSimplePreferenceState(alwaysOnTopCheck))); alwaysOnTop.setVisible(true); alwaysOnTop.setToolTipText(Bundle.getMessage("ToolTipOnTop")); alwaysOnTop.addActionListener( (ActionEvent event) -> { frame.setAlwaysOnTop(alwaysOnTop.isSelected()); pref.setSimplePreferenceState(alwaysOnTopCheck, alwaysOnTop.isSelected()); }); frame.setAlwaysOnTop(alwaysOnTop.isSelected()); // Define the pop-up menu copySelection = new JMenuItem(Bundle.getMessage("MenuItemCopy")); copySelection.addActionListener( (ActionEvent event) -> { StringSelection text = new StringSelection(console.getSelectedText()); clipboard.setContents(text, text); }); popup.add(copySelection); JMenuItem menuItem = new JMenuItem(Bundle.getMessage("ButtonCopyClip")); menuItem.addActionListener( (ActionEvent event) -> { StringSelection text = new StringSelection(console.getText()); clipboard.setContents(text, text); }); popup.add(menuItem); popup.add(new JSeparator()); JRadioButtonMenuItem rbMenuItem; // Define the colour scheme sub-menu schemeMenu = new JMenu(rbc.getString("ConsoleSchemeMenu")); schemeGroup = new ButtonGroup(); for (final Scheme s : schemes) { rbMenuItem = new JRadioButtonMenuItem(s.description); rbMenuItem.addActionListener( (ActionEvent event) -> { setScheme(schemes.indexOf(s)); }); rbMenuItem.setSelected(getScheme() == schemes.indexOf(s)); schemeMenu.add(rbMenuItem); schemeGroup.add(rbMenuItem); } popup.add(schemeMenu); // Define the wrap style sub-menu wrapMenu = new JMenu(rbc.getString("ConsoleWrapStyleMenu")); wrapGroup = new ButtonGroup(); rbMenuItem = new JRadioButtonMenuItem(rbc.getString("ConsoleWrapStyleNone")); rbMenuItem.addActionListener( (ActionEvent event) -> { setWrapStyle(WRAP_STYLE_NONE); }); rbMenuItem.setSelected(getWrapStyle() == WRAP_STYLE_NONE); wrapMenu.add(rbMenuItem); wrapGroup.add(rbMenuItem); rbMenuItem = new JRadioButtonMenuItem(rbc.getString("ConsoleWrapStyleLine")); rbMenuItem.addActionListener( (ActionEvent event) -> { setWrapStyle(WRAP_STYLE_LINE); }); rbMenuItem.setSelected(getWrapStyle() == WRAP_STYLE_LINE); wrapMenu.add(rbMenuItem); wrapGroup.add(rbMenuItem); rbMenuItem = new JRadioButtonMenuItem(rbc.getString("ConsoleWrapStyleWord")); rbMenuItem.addActionListener( (ActionEvent event) -> { setWrapStyle(WRAP_STYLE_WORD); }); rbMenuItem.setSelected(getWrapStyle() == WRAP_STYLE_WORD); wrapMenu.add(rbMenuItem); wrapGroup.add(rbMenuItem); popup.add(wrapMenu); // Bind pop-up to objects MouseListener popupListener = new PopupListener(); console.addMouseListener(popupListener); frame.addMouseListener(popupListener); // Add document listener to scroll to end when modified if required console .getDocument() .addDocumentListener( new DocumentListener() { // References to the JTextArea and JCheckBox // of this instantiation JTextArea ta = console; JCheckBox chk = autoScroll; @Override public void insertUpdate(DocumentEvent e) { doAutoScroll(ta, chk.isSelected()); } @Override public void removeUpdate(DocumentEvent e) { doAutoScroll(ta, chk.isSelected()); } @Override public void changedUpdate(DocumentEvent e) { doAutoScroll(ta, chk.isSelected()); } }); // Add the button panel to the frame & then arrange everything frame.add(p, BorderLayout.SOUTH); frame.pack(); }