/* LanguageTool, a natural language style checker * Copyright (C) 2005 Daniel Naber (http://www.danielnaber.de) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * USA */ package org.languagetool.gui; import org.languagetool.AnalyzedSentence; import org.languagetool.JLanguageTool; import org.languagetool.Language; import org.languagetool.rules.Rule; import org.languagetool.server.HTTPServer; import org.languagetool.server.HTTPServerConfig; import org.languagetool.server.PortBindingException; import org.languagetool.tools.JnaTools; import org.languagetool.tools.StringTools; import javax.swing.*; import javax.swing.filechooser.FileFilter; import java.awt.*; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.event.*; import java.io.*; import java.net.URL; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; import javax.swing.text.DefaultEditorKit; import javax.swing.text.JTextComponent; import javax.swing.text.TextAction; import org.apache.commons.collections4.queue.CircularFifoQueue; import org.apache.commons.io.ByteOrderMark; import org.apache.commons.io.FileUtils; import org.apache.commons.io.input.BOMInputStream; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.languagetool.AnalyzedToken; import org.languagetool.AnalyzedTokenReadings; /** * A simple GUI to check texts with. * * @author Daniel Naber */ public final class Main { static final String EXTERNAL_LANGUAGE_SUFFIX = " (ext.)"; private static final String HTML_FONT_START = "<font face='Arial,Helvetica'>"; private static final String HTML_FONT_END = "</font>"; private static final String TRAY_ICON = "/TrayIcon.png"; private static final String TRAY_SERVER_ICON = "/TrayIconWithServer.png"; private static final String TRAY_SMALL_ICON = "/TrayIconSmall.png"; private static final String TRAY_SMALL_SERVER_ICON = "/TrayIconSmallWithServer.png"; private static final String TRAY_TOOLTIP = "LanguageTool"; private static final String TAG_COLOR = "#888888"; private static final int WINDOW_WIDTH = 600; private static final int WINDOW_HEIGHT = 550; private static final int MAX_RECENT_FILES = 8; private final ResourceBundle messages; private final List<Language> externalLanguages = new ArrayList<>(); private JFrame frame; private JDialog taggerDialog; private JTextPane taggerArea; private JTextArea textArea; private JTextPane resultArea; private LanguageComboBox languageBox; private CheckboxMenuItem enableHttpServerItem; private HTTPServer httpServer; private TrayIcon trayIcon; private boolean closeHidesToTray; private boolean isInTray; private boolean taggerShowsDisambigLog = false; private LanguageToolSupport ltSupport; private OpenAction openAction; private SaveAction saveAction; private SaveAsAction saveAsAction; private AutoCheckAction autoCheckAction; private ShowResultAction showResultAction; private CheckAction checkAction; private File currentFile; private ByteOrderMark bom; private UndoRedoSupport undoRedo; private final JLabel statusLabel = new JLabel(" ", null, SwingConstants.RIGHT); private FontChooser fontChooserDialog; private final CircularFifoQueue<String> recentFiles = new CircularFifoQueue<>(MAX_RECENT_FILES); private JMenu recentFilesMenu; private final LocalStorage localStorage; private final Map<Language, ConfigurationDialog> configDialogs = new HashMap<>(); private JSplitPane splitPane; private final JPanel mainPanel = new JPanel(); private Main(LocalStorage localStorage) { this.localStorage = localStorage; messages = JLanguageTool.getMessageBundle(); } private void loadFile() { File file = Tools.openFileDialog(frame, new PlainTextFileFilter()); if (file == null) { // user clicked cancel return; } loadFile(file); } private void loadFile(File file) { try (FileInputStream inputStream = new FileInputStream(file)) { BOMInputStream bomIn = new BOMInputStream(inputStream, false, ByteOrderMark.UTF_8, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_32BE, ByteOrderMark.UTF_32LE); String charsetName; if (bomIn.hasBOM() == false) { // No BOM found bom = null; charsetName = null; } else { bom = bomIn.getBOM(); charsetName = bom.getCharsetName(); } String fileContents = StringTools.readStream(bomIn, charsetName); textArea.setText(fileContents); currentFile = file; updateTitle(); if(recentFiles.contains(file.getAbsolutePath())) { recentFiles.remove(file.getAbsolutePath()); } recentFiles.add(file.getAbsolutePath()); localStorage.saveProperty("recentFiles", recentFiles); updateRecentFilesMenu(); } catch (IOException e) { Tools.showError(e); } } private void saveFile(boolean newFile) { if (currentFile == null || newFile) { JFileChooser jfc = new JFileChooser(); jfc.setFileFilter(new PlainTextFileFilter()); jfc.showSaveDialog(frame); File file = jfc.getSelectedFile(); if (file == null) { // user clicked cancel return; } currentFile = file; bom = null; updateTitle(); } try { if(bom != null) { FileUtils.writeByteArrayToFile(currentFile, bom.getBytes()); FileUtils.write(currentFile, textArea.getText(), bom.getCharsetName(), true); } else { FileUtils.write(currentFile, textArea.getText(), Charset.defaultCharset()); } } catch (IOException ex) { Tools.showError(ex); } } private void addLanguage() throws InstantiationException, IllegalAccessException { LanguageManagerDialog dialog = new LanguageManagerDialog(frame, externalLanguages); dialog.show(); List<Language> newExtLanguages = dialog.getLanguages(); externalLanguages.clear(); externalLanguages.addAll(newExtLanguages); languageBox.setModel(LanguageComboBoxModel.create(messages, EXTERNAL_LANGUAGE_SUFFIX, false, externalLanguages, null)); languageBox.selectLanguage(ltSupport.getLanguage()); } private void showOptions() { JLanguageTool langTool = ltSupport.getLanguageTool(); List<Rule> rules = langTool.getAllRules(); ConfigurationDialog configDialog = getCurrentConfigDialog(); configDialog.show(rules); // this blocks until OK/Cancel is clicked in the dialog Configuration config = ltSupport.getConfig(); try { //save config - needed for the server config.saveConfiguration(langTool.getLanguage()); } catch (IOException e) { Tools.showError(e); } ltSupport.reloadConfig(); // Stop server, start new server if requested: stopServer(); maybeStartServer(); } private void showSelectFontDialog() { Configuration config = ltSupport.getConfig(); if (fontChooserDialog == null) { fontChooserDialog = new FontChooser(frame, true); Tools.centerDialog(fontChooserDialog); } fontChooserDialog.setSelectedFont(this.textArea.getFont()); fontChooserDialog.setVisible(true); if (fontChooserDialog.getSelectedFont() != null) { this.textArea.setFont(fontChooserDialog.getSelectedFont()); config.setFontName(fontChooserDialog.getSelectedFont().getFamily()); config.setFontStyle(fontChooserDialog.getSelectedFont().getStyle()); config.setFontSize(fontChooserDialog.getSelectedFont().getSize()); try { config.saveConfiguration(ltSupport.getLanguage()); } catch (IOException e) { Tools.showError(e); } } } private Component getFrame() { return frame; } private void updateTitle() { StringBuilder sb = new StringBuilder(); if(currentFile != null) { sb.append(currentFile.getName()); if(bom != null) { sb.append(" (").append(bom.getCharsetName()).append(')'); } sb.append(" - "); } sb.append("LanguageTool ").append(JLanguageTool.VERSION); frame.setTitle(sb.toString()); } private void createGUI() { loadRecentFiles(); frame = new JFrame("LanguageTool " + JLanguageTool.VERSION); setLookAndFeel(); openAction = new OpenAction(); saveAction = new SaveAction(); saveAsAction = new SaveAsAction(); checkAction = new CheckAction(); autoCheckAction = new AutoCheckAction(true); showResultAction = new ShowResultAction(true); frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); frame.addWindowListener(new CloseListener()); URL iconUrl = JLanguageTool.getDataBroker().getFromResourceDirAsUrl(TRAY_ICON); frame.setIconImage(new ImageIcon(iconUrl).getImage()); textArea = new JTextArea(); textArea.setLineWrap(true); textArea.setWrapStyleWord(true); textArea.addKeyListener(new ControlReturnTextCheckingListener()); resultArea = new JTextPane(); undoRedo = new UndoRedoSupport(this.textArea, messages); frame.setJMenuBar(createMenuBar()); GridBagConstraints buttonCons = new GridBagConstraints(); JPanel insidePanel = new JPanel(); insidePanel.setOpaque(false); insidePanel.setLayout(new GridBagLayout()); buttonCons.gridx = 0; buttonCons.gridy = 0; buttonCons.anchor = GridBagConstraints.LINE_START; insidePanel.add(new JLabel(messages.getString("textLanguage") + " "), buttonCons); //create a ComboBox with flags, do not include hidden languages languageBox = LanguageComboBox.create(messages, EXTERNAL_LANGUAGE_SUFFIX, true, false); buttonCons.gridx = 1; buttonCons.gridy = 0; buttonCons.anchor = GridBagConstraints.LINE_START; insidePanel.add(languageBox, buttonCons); JCheckBox autoDetectBox = new JCheckBox(messages.getString("atd")); buttonCons.gridx = 2; buttonCons.gridy = 0; buttonCons.gridwidth = GridBagConstraints.REMAINDER; buttonCons.anchor = GridBagConstraints.LINE_START; insidePanel.add(autoDetectBox, buttonCons); buttonCons.gridx = 0; buttonCons.gridy = 1; buttonCons.gridwidth = GridBagConstraints.REMAINDER; buttonCons.fill = GridBagConstraints.HORIZONTAL; buttonCons.anchor = GridBagConstraints.LINE_END; buttonCons.weightx = 1.0; insidePanel.add(statusLabel, buttonCons); Container contentPane = frame.getContentPane(); GridBagLayout gridLayout = new GridBagLayout(); contentPane.setLayout(gridLayout); GridBagConstraints cons = new GridBagConstraints(); cons.gridx = 0; cons.gridy = 1; cons.fill = GridBagConstraints.HORIZONTAL; cons.anchor = GridBagConstraints.FIRST_LINE_START; JToolBar toolbar = new JToolBar("Toolbar", JToolBar.HORIZONTAL); toolbar.setFloatable(false); contentPane.add(toolbar,cons); JButton openButton = new JButton(openAction); openButton.setHideActionText(true); openButton.setFocusable(false); toolbar.add(openButton); JButton saveButton = new JButton(saveAction); saveButton.setHideActionText(true); saveButton.setFocusable(false); toolbar.add(saveButton); JButton saveAsButton = new JButton(saveAsAction); saveAsButton.setHideActionText(true); saveAsButton.setFocusable(false); toolbar.add(saveAsButton); JButton spellButton = new JButton(this.checkAction); spellButton.setHideActionText(true); spellButton.setFocusable(false); toolbar.add(spellButton); JToggleButton autoSpellButton = new JToggleButton(autoCheckAction); autoSpellButton.setHideActionText(true); autoSpellButton.setFocusable(false); toolbar.add(autoSpellButton); JButton clearTextButton = new JButton(new ClearTextAction()); clearTextButton.setHideActionText(true); clearTextButton.setFocusable(false); toolbar.add(clearTextButton); cons.insets = new Insets(5, 5, 5, 5); cons.fill = GridBagConstraints.BOTH; cons.weightx = 10.0f; cons.weighty = 10.0f; cons.gridx = 0; cons.gridy = 2; cons.weighty = 5.0f; splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, new JScrollPane(textArea), new JScrollPane(resultArea)); mainPanel.setLayout(new GridLayout(0,1)); contentPane.add(mainPanel, cons); mainPanel.add(splitPane); cons.fill = GridBagConstraints.HORIZONTAL; cons.gridx = 0; cons.gridy = 3; cons.weightx = 1.0f; cons.weighty = 0.0f; cons.insets = new Insets(4, 12, 4, 12); contentPane.add(insidePanel, cons); ltSupport = new LanguageToolSupport(this.frame, this.textArea, this.undoRedo); ResultAreaHelper.install(messages, ltSupport, resultArea); languageBox.selectLanguage(ltSupport.getLanguage()); languageBox.setEnabled(!ltSupport.getConfig().getAutoDetect()); autoDetectBox.setSelected(ltSupport.getConfig().getAutoDetect()); taggerShowsDisambigLog = ltSupport.getConfig().getTaggerShowsDisambigLog(); languageBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { // we cannot re-use the existing LT object anymore frame.applyComponentOrientation( ComponentOrientation.getOrientation(Locale.getDefault())); Language lang = languageBox.getSelectedLanguage(); ComponentOrientation componentOrientation = ComponentOrientation.getOrientation(lang.getLocale()); textArea.applyComponentOrientation(componentOrientation); resultArea.applyComponentOrientation(componentOrientation); ltSupport.setLanguage(lang); } } }); autoDetectBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { boolean selected = e.getStateChange() == ItemEvent.SELECTED; languageBox.setEnabled(!selected); ltSupport.getConfig().setAutoDetect(selected); if (selected) { Language detected = ltSupport.autoDetectLanguage(textArea.getText()); languageBox.selectLanguage(detected); } } }); ltSupport.addLanguageToolListener(new LanguageToolListener() { @Override public void languageToolEventOccurred(LanguageToolEvent event) { if (event.getType() == LanguageToolEvent.Type.CHECKING_STARTED) { String msg = org.languagetool.tools.Tools.i18n(messages, "checkStart"); statusLabel.setText(msg); if (event.getCaller() == getFrame()) { setWaitCursor(); checkAction.setEnabled(false); } } else if (event.getType() == LanguageToolEvent.Type.CHECKING_FINISHED) { if (event.getCaller() == getFrame()) { checkAction.setEnabled(true); unsetWaitCursor(); } String msg = org.languagetool.tools.Tools.i18n(messages, "checkDone", event.getSource().getMatches().size(), event.getElapsedTime()); statusLabel.setText(msg); } else if (event.getType() == LanguageToolEvent.Type.LANGUAGE_CHANGED) { languageBox.selectLanguage(ltSupport.getLanguage()); } else if (event.getType() == LanguageToolEvent.Type.RULE_ENABLED) { //this will trigger a check and the result will be updated by //the CHECKING_FINISHED event } else if (event.getType() == LanguageToolEvent.Type.RULE_DISABLED) { String msg = org.languagetool.tools.Tools.i18n(messages, "checkDoneNoTime", event.getSource().getMatches().size()); statusLabel.setText(msg); } } }); frame.applyComponentOrientation(ComponentOrientation.getOrientation(Locale.getDefault())); Language lang = ltSupport.getLanguage(); ComponentOrientation componentOrientation = ComponentOrientation.getOrientation(lang.getLocale()); textArea.applyComponentOrientation(componentOrientation); resultArea.applyComponentOrientation(componentOrientation); ResourceBundle textLanguageMessageBundle = JLanguageTool.getMessageBundle(ltSupport.getLanguage()); textArea.setText(textLanguageMessageBundle.getString("guiDemoText")); Configuration config = ltSupport.getConfig(); if (config.getFontName() != null || config.getFontStyle() != Configuration.FONT_STYLE_INVALID || config.getFontSize() != Configuration.FONT_SIZE_INVALID) { String fontName = config.getFontName(); if (fontName == null) { fontName = textArea.getFont().getFamily(); } int fontSize = config.getFontSize(); if (fontSize == Configuration.FONT_SIZE_INVALID) { fontSize = textArea.getFont().getSize(); } Font font = new Font(fontName, config.getFontStyle(), fontSize); textArea.setFont(font); } frame.pack(); frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT); frame.setLocationByPlatform(true); splitPane.setDividerLocation(200); MainWindowStateBean state = localStorage.loadProperty("gui.state", MainWindowStateBean.class); if(state != null) { if(state.getBounds() != null) { frame.setBounds(state.getBounds()); ResizeComponentListener.setBoundsProperty(frame, state.getBounds()); } if(state.getDividerLocation() != null) { splitPane.setDividerLocation(state.getDividerLocation()); } if(state.getState() != null) { frame.setExtendedState(state.getState()); } } ResizeComponentListener.attachToWindow(frame); maybeStartServer(); } private String getLabel(String key) { return Tools.getLabel(messages.getString(key)); } private int getMnemonic(String key) { return Tools.getMnemonic(messages.getString(key)); } private KeyStroke getMenuKeyStroke(int keyEvent) { return KeyStroke.getKeyStroke(keyEvent, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()); } private JMenuBar createMenuBar() { JMenuBar menuBar = new JMenuBar(); JMenu fileMenu = new JMenu(getLabel("guiMenuFile")); fileMenu.setMnemonic(getMnemonic("guiMenuFile")); JMenu editMenu = new JMenu(getLabel("guiMenuEdit")); editMenu.setMnemonic(getMnemonic("guiMenuEdit")); JMenu grammarMenu = new JMenu(getLabel("guiMenuGrammar")); grammarMenu.setMnemonic(getMnemonic("guiMenuGrammar")); JMenu helpMenu = new JMenu(getLabel("guiMenuHelp")); helpMenu.setMnemonic(getMnemonic("guiMenuHelp")); fileMenu.add(openAction); fileMenu.add(saveAction); fileMenu.add(saveAsAction); recentFilesMenu = new JMenu(getLabel("guiMenuRecentFiles")); recentFilesMenu.setMnemonic(getMnemonic("guiMenuRecentFiles")); fileMenu.add(recentFilesMenu); updateRecentFilesMenu(); fileMenu.addSeparator(); fileMenu.add(new HideAction()); fileMenu.addSeparator(); fileMenu.add(new QuitAction()); grammarMenu.add(checkAction); JCheckBoxMenuItem item = new JCheckBoxMenuItem(autoCheckAction); grammarMenu.add(item); JCheckBoxMenuItem showResult = new JCheckBoxMenuItem(showResultAction); grammarMenu.add(showResult); grammarMenu.add(new CheckClipboardAction()); grammarMenu.add(new TagTextAction()); grammarMenu.add(new AddRulesAction()); grammarMenu.add(new OptionsAction()); grammarMenu.add(new SelectFontAction()); JMenu lafMenu = new JMenu(messages.getString("guiLookAndFeelMenu")); UIManager.LookAndFeelInfo[] lafInfo = UIManager.getInstalledLookAndFeels(); ButtonGroup buttonGroup = new ButtonGroup(); for (UIManager.LookAndFeelInfo laf : lafInfo) { if (!"Nimbus".equals(laf.getName())) { continue; } addLookAndFeelMenuItem(lafMenu, laf, buttonGroup); } for (UIManager.LookAndFeelInfo laf : lafInfo) { if ("Nimbus".equals(laf.getName())) { continue; } addLookAndFeelMenuItem(lafMenu, laf, buttonGroup); } grammarMenu.add(lafMenu); helpMenu.add(new AboutAction()); undoRedo.undoAction.putValue(Action.NAME, getLabel("guiMenuUndo")); undoRedo.undoAction.putValue(Action.MNEMONIC_KEY, getMnemonic("guiMenuUndo")); undoRedo.redoAction.putValue(Action.NAME, getLabel("guiMenuRedo")); undoRedo.redoAction.putValue(Action.MNEMONIC_KEY, getMnemonic("guiMenuRedo")); editMenu.add(undoRedo.undoAction); editMenu.add(undoRedo.redoAction); editMenu.addSeparator(); Action cutAction = new DefaultEditorKit.CutAction(); cutAction.putValue(Action.SMALL_ICON, getImageIcon("sc_cut.png")); cutAction.putValue(Action.LARGE_ICON_KEY, getImageIcon("lc_cut.png")); cutAction.putValue(Action.NAME, getLabel("guiMenuCut")); cutAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_T); editMenu.add(cutAction); Action copyAction = new DefaultEditorKit.CopyAction(); copyAction.putValue(Action.SMALL_ICON, getImageIcon("sc_copy.png")); copyAction.putValue(Action.LARGE_ICON_KEY, getImageIcon("lc_copy.png")); copyAction.putValue(Action.NAME, getLabel("guiMenuCopy")); copyAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_C); editMenu.add(copyAction); Action pasteAction = new DefaultEditorKit.PasteAction(); pasteAction.putValue(Action.SMALL_ICON, getImageIcon("sc_paste.png")); pasteAction.putValue(Action.LARGE_ICON_KEY, getImageIcon("lc_paste.png")); pasteAction.putValue(Action.NAME, getLabel("guiMenuPaste")); pasteAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_P); editMenu.add(pasteAction); editMenu.addSeparator(); editMenu.add(new SelectAllAction()); menuBar.add(fileMenu); menuBar.add(editMenu); menuBar.add(grammarMenu); menuBar.add(helpMenu); return menuBar; } private void updateRecentFilesMenu() { recentFilesMenu.removeAll(); String[] files = recentFiles.toArray(new String[recentFiles.size()]); ArrayUtils.reverse(files); for(String filename : files) { recentFilesMenu.add(new RecentFileAction(new File(filename))); } } private void loadRecentFiles() { CircularFifoQueue<String> l = localStorage.loadProperty("recentFiles", CircularFifoQueue.class); if(l != null) { for(String name : l) { File f = new File(name); if(f.exists() && f.isFile()) { recentFiles.add(name); } } } } private void addLookAndFeelMenuItem(JMenu lafMenu, UIManager.LookAndFeelInfo laf, ButtonGroup buttonGroup) { JRadioButtonMenuItem lfItem = new JRadioButtonMenuItem(new SelectLFAction(laf)); lafMenu.add(lfItem); buttonGroup.add(lfItem); if (laf.getClassName().equals(UIManager.getLookAndFeel().getClass().getName())) { buttonGroup.setSelected(lfItem.getModel(), true); } } private void setLookAndFeel() { String lookAndFeelName = null; String className = null; try { Configuration config = new Configuration(new File(System.getProperty("user.home")), LanguageToolSupport.CONFIG_FILE, null); if (config.getLookAndFeelName() != null) { lookAndFeelName = config.getLookAndFeelName(); } } catch (IOException ex) { // ignore } if (lookAndFeelName == null) { lookAndFeelName = "Nimbus"; // to use the system's look and feel: //lookAndFeelName = UIManager.getSystemLookAndFeelClassName(); } for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { if (lookAndFeelName.equals(info.getName())) { className = info.getClassName(); break; } } if (className != null) { try { UIManager.setLookAndFeel(className); } catch (Exception ignored) { // Well, what can we do... } } } private PopupMenu makePopupMenu() { PopupMenu popup = new PopupMenu(); ActionListener rmbListener = new TrayActionRMBListener(); // Enable or disable embedded HTTP server: enableHttpServerItem = new CheckboxMenuItem(Tools.getLabel(messages.getString("tray_menu_enable_server"))); enableHttpServerItem.setState(httpServer != null && httpServer.isRunning()); enableHttpServerItem.addItemListener(new TrayActionItemListener()); popup.add(enableHttpServerItem); // Check clipboard text: MenuItem checkClipboardItem = new MenuItem(Tools.getLabel(messages.getString("guiMenuCheckClipboard"))); checkClipboardItem.addActionListener(rmbListener); popup.add(checkClipboardItem); // Open main window: MenuItem restoreItem = new MenuItem(Tools.getLabel(messages.getString("guiMenuShowMainWindow"))); restoreItem.addActionListener(rmbListener); popup.add(restoreItem); // Exit: MenuItem exitItem = new MenuItem(Tools.getLabel(messages.getString("guiMenuQuit"))); exitItem.addActionListener(rmbListener); popup.add(exitItem); return popup; } private void checkClipboardText() { String s = getClipboardText(); textArea.setText(s); } private void hideToTray() { if (!isInTray) { SystemTray tray = SystemTray.getSystemTray(); String iconPath = tray.getTrayIconSize().height > 16 ? TRAY_ICON : TRAY_SMALL_ICON; URL iconUrl = JLanguageTool.getDataBroker().getFromResourceDirAsUrl(iconPath); Image img = Toolkit.getDefaultToolkit().getImage(iconUrl); PopupMenu popup = makePopupMenu(); try { trayIcon = new TrayIcon(img, TRAY_TOOLTIP, popup); trayIcon.addMouseListener(new TrayActionListener()); setTrayIcon(); tray.add(trayIcon); } catch (AWTException e1) { Tools.showError(e1); } } isInTray = true; frame.setVisible(false); } private void tagText() { if (StringTools.isEmpty(textArea.getText().trim())) { textArea.setText(messages.getString("enterText2")); return; } setWaitCursor(); new Thread() { @Override public void run() { try { tagTextAndDisplayResults(); } finally { SwingUtilities.invokeLater(() -> unsetWaitCursor()); } } }.start(); } private void quitOrHide() { if (closeHidesToTray) { hideToTray(); } else { quit(); } } private void quit() { stopServer(); try { Configuration config = ltSupport.getConfig(); config.setLanguage(ltSupport.getLanguage()); config.saveConfiguration(ltSupport.getLanguage()); } catch (IOException e) { Tools.showError(e); } MainWindowStateBean bean = new MainWindowStateBean(); bean.setBounds(ResizeComponentListener.getBoundsProperty(frame)); bean.setState(frame.getExtendedState()); Component comp = mainPanel.getComponent(0); if(comp instanceof JSplitPane) { bean.setDividerLocation(((JSplitPane)comp).getDividerLocation()); } else { MainWindowStateBean old = localStorage.loadProperty("gui.state", MainWindowStateBean.class); bean.setDividerLocation(old.getDividerLocation()); } localStorage.saveProperty("gui.state", bean); frame.setVisible(false); JLanguageTool.removeTemporaryFiles(); System.exit(0); } private void setTrayIcon() { if (trayIcon != null) { SystemTray tray = SystemTray.getSystemTray(); boolean httpServerRunning = httpServer != null && httpServer.isRunning(); boolean smallTray = tray.getTrayIconSize().height <= 16; String iconPath; if (httpServerRunning) { trayIcon.setToolTip(messages.getString("tray_tooltip_server_running")); iconPath = smallTray ? TRAY_SMALL_SERVER_ICON : TRAY_SERVER_ICON; } else { trayIcon.setToolTip(TRAY_TOOLTIP); iconPath = smallTray ? TRAY_SMALL_ICON : TRAY_ICON; } URL iconUrl = JLanguageTool.getDataBroker().getFromResourceDirAsUrl(iconPath); Image img = Toolkit.getDefaultToolkit().getImage(iconUrl); trayIcon.setImage(img); } } private void showGUI() { frame.setVisible(true); } private void restoreFromTray() { frame.setVisible(true); } // show GUI and check the text from clipboard/selection: private void restoreFromTrayAndCheck() { String s = getClipboardText(); restoreFromTray(); textArea.setText(s); } private String getClipboardText() { // get text from clipboard or selection: Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemSelection(); if (clipboard == null) { // on Windows clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); } String s; Transferable data = clipboard.getContents(this); try { if (data != null && data.isDataFlavorSupported(DataFlavor.getTextPlainUnicodeFlavor())) { DataFlavor df = DataFlavor.getTextPlainUnicodeFlavor(); try (Reader sr = df.getReaderForText(data)) { s = StringTools.readerToString(sr); } } else { s = ""; } } catch (Exception ex) { s = data.toString(); } return s; } private boolean maybeStartServer() { Configuration config = ltSupport.getConfig(); if (config.getRunServer()) { try { HTTPServerConfig serverConfig = new HTTPServerConfig(config.getServerPort(), false); httpServer = new HTTPServer(serverConfig, true); httpServer.run(); if (enableHttpServerItem != null) { enableHttpServerItem.setState(httpServer.isRunning()); setTrayIcon(); } } catch (PortBindingException e) { JOptionPane.showMessageDialog(null, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } } return httpServer != null && httpServer.isRunning(); } private void stopServer() { if (httpServer != null) { httpServer.stop(); if (enableHttpServerItem != null) { enableHttpServerItem.setState(httpServer.isRunning()); setTrayIcon(); } httpServer = null; } } private void checkTextAndDisplayResults() { if (StringTools.isEmpty(textArea.getText().trim())) { textArea.setText(messages.getString("enterText2")); return; } ltSupport.checkImmediately(getFrame()); } private String getStackTraceAsHtml(Exception e) { return "<br><br><b><font color=\"red\">" + org.languagetool.tools.Tools.getFullStackTrace(e).replace("\n", "<br/>") + "</font></b><br>"; } private void setWaitCursor() { frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); // For some reason we also have to set the cursor here so it also shows // when user starts checking text with Ctrl+Return: textArea.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); resultArea.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); } private void unsetWaitCursor() { frame.setCursor(Cursor.getDefaultCursor()); textArea.setCursor(Cursor.getDefaultCursor()); resultArea.setCursor(Cursor.getDefaultCursor()); } private boolean appendTagsWithDisambigLog(StringBuilder sb, AnalyzedSentence sentence, boolean odd) { for (AnalyzedTokenReadings t : sentence.getTokens()) { if (t.isWhitespace() && !t.isSentenceStart()) { continue; } odd = !odd; sb.append("<tr>"); sb.append("<td bgcolor=\""); if(odd) { sb.append("#ffffff"); } else { sb.append("#f1f1f1"); } sb.append("\">"); if(!t.isWhitespace()) { sb.append(t.getToken()); sb.append("<font color='"); sb.append(TAG_COLOR); sb.append("'>["); } Iterator<AnalyzedToken> iterator = t.iterator(); while (iterator.hasNext()) { AnalyzedToken token = iterator.next(); String posTag = token.getPOSTag(); if (t.isSentenceStart()) { sb.append(StringTools.escapeHTML("<S>")); } else if (JLanguageTool.SENTENCE_END_TAGNAME.equals(posTag)) { sb.append(StringTools.escapeHTML("</S>")); } else if (JLanguageTool.PARAGRAPH_END_TAGNAME.equals(posTag)) { sb.append(StringTools.escapeHTML("<P/>")); } else { if (!t.isWhitespace()) { sb.append(token); if (iterator.hasNext()) { sb.append(", "); } } } } if (!t.isWhitespace()) { if (t.getChunkTags().size() > 0) { sb.append(','); sb.append(StringUtils.join(t.getChunkTags(), "|")); } if (t.isImmunized()) { sb.append("{!}"); } sb.append("]</font>"); } else { sb.append(' '); } sb.append("</td>"); sb.append("<td bgcolor=\""); if(odd) { sb.append("#ffffff"); } else { sb.append("#f1f1f1"); } sb.append("\">"); if (!"".equals(t.getHistoricalAnnotations())) { sb.append(StringTools.escapeHTML(t.getHistoricalAnnotations()) .trim().replace("\n", "<br>")); } sb.append("</td>"); sb.append("</tr>"); } return odd; } private void tagTextAndDisplayResults() { JLanguageTool langTool = ltSupport.getLanguageTool(); // tag text List<String> sentences = langTool.sentenceTokenize(textArea.getText()); StringBuilder sb = new StringBuilder(); if(taggerShowsDisambigLog) { sb.append("<table>"); sb.append("<tr>"); sb.append("<td><b>"); sb.append(messages.getString("token")); sb.append("</b></td>"); sb.append("<td><b>"); sb.append(messages.getString("disambiguatorLog")); sb.append("</b></td>"); sb.append("</tr>"); boolean odd = true; try { for (String sent : sentences) { AnalyzedSentence analyzed = langTool.getAnalyzedSentence(sent); odd = appendTagsWithDisambigLog(sb, analyzed, odd); } } catch (Exception e) { sb.append(getStackTraceAsHtml(e)); } sb.append("</table>"); } else { try { for (String sent : sentences) { AnalyzedSentence analyzed = langTool.getAnalyzedSentence(sent); String analyzedString = StringTools.escapeHTML(analyzed.toString(",")). replace("<S>", "<S><br>"). replace("[", "<font color='" + TAG_COLOR + "'>["). replace("]", "]</font><br>"); sb.append(analyzedString).append('\n'); } } catch (Exception e) { sb.append(getStackTraceAsHtml(e)); } } SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (taggerDialog == null) { taggerDialog = new JDialog(frame); taggerDialog.setTitle(messages.getString("taggerWindowTitle")); taggerDialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE); taggerDialog.setResizable(true); taggerDialog.setSize(640, 480); taggerDialog.setLocationRelativeTo(frame); KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); ActionListener actionListener = actionEvent -> taggerDialog.setVisible(false); taggerDialog.getRootPane().registerKeyboardAction(actionListener, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); JPanel panel = new JPanel(new GridBagLayout()); taggerDialog.add(panel); taggerArea = new JTextPane(); taggerArea.setContentType("text/html"); taggerArea.setEditable(false); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridwidth = 2; c.gridy = 0; c.weightx = 1.0; c.weighty = 1.0; c.insets = new Insets(8,8,4,8); c.fill = GridBagConstraints.BOTH; panel.add(new JScrollPane(taggerArea),c); c.gridwidth = 1; c.gridx = 0; c.gridy = 1; c.weightx = 0.0; c.weighty = 0.0; c.insets = new Insets(4,8,8,8); c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.EAST; JCheckBox showDisAmbig = new JCheckBox(messages.getString("ShowDisambiguatorLog")); showDisAmbig.setSelected(taggerShowsDisambigLog); showDisAmbig.addItemListener((ItemEvent e) -> { taggerShowsDisambigLog = e.getStateChange() == ItemEvent.SELECTED; ltSupport.getConfig().setTaggerShowsDisambigLog(taggerShowsDisambigLog); }); panel.add(showDisAmbig,c); c.gridx = 1; JButton closeButton = new JButton( messages.getString("guiCloseButton")); closeButton.addActionListener(actionListener); panel.add(closeButton,c); } // orientation each time should be set as language may is changed taggerDialog.applyComponentOrientation(ComponentOrientation.getOrientation( languageBox.getSelectedLanguage().getLocale())); taggerDialog.setVisible(true); taggerArea.setText(HTML_FONT_START + sb + HTML_FONT_END); } }); } private void setResultAreaVisible(boolean enable) { if (enable) { this.mainPanel.removeAll(); mainPanel.add(this.splitPane); splitPane.setTopComponent(new JScrollPane(textArea)); splitPane.setDividerLocation(200); MainWindowStateBean state = localStorage.loadProperty("gui.state", MainWindowStateBean.class); if (state != null && state.getDividerLocation() != null) { splitPane.setDividerLocation(state.getDividerLocation()); } ResultAreaHelper.enable(resultArea); } else { MainWindowStateBean bean = new MainWindowStateBean(); bean.setDividerLocation(splitPane.getDividerLocation()); localStorage.saveProperty("gui.state", bean); this.mainPanel.removeAll(); splitPane.setTopComponent(null); mainPanel.add(new JScrollPane(textArea)); ResultAreaHelper.disable(resultArea); } mainPanel.validate(); } private void setTrayMode(boolean trayMode) { this.closeHidesToTray = trayMode; } public static void main(String[] args) { if (System.getSecurityManager() == null) { JnaTools.setBugWorkaroundProperty(); } LocalStorage localStorage = new LocalStorage(); LocaleBean bean = localStorage.loadProperty("gui.locale", LocaleBean.class); if(bean != null) { Locale.setDefault(bean.asLocale()); } Main prg = new Main(localStorage); if (args.length == 1 && (args[0].equals("-t") || args[0].equals("--tray"))) { // dock to systray on startup SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { prg.createGUI(); prg.setTrayMode(true); prg.hideToTray(); } catch (Exception e) { Tools.showError(e); System.exit(1); } } }); } else if (args.length == 1 && (args[0].equals("-h") || args[0].equals("--help"))) { printUsage(); } else if (args.length == 0 || args.length == 1) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { prg.createGUI(); prg.showGUI(); if (args.length == 1) { prg.loadFile(new File(args[0])); } } catch (Exception e) { Tools.showError(e); } } }); } else { printUsage(); System.exit(1); } } private static void printUsage() { System.out.println("Usage: java org.languagetool.gui.Main [-t|--tray]"); System.out.println(" or java org.languagetool.gui.Main [file]"); System.out.println("Parameters:"); System.out.println(" -t, --tray: dock LanguageTool to system tray on startup"); System.out.println(" file: a plain text file to load on startup"); } private class ControlReturnTextCheckingListener extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { if ((e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) == KeyEvent.CTRL_DOWN_MASK) { checkTextAndDisplayResults(); } } } } // // The System Tray stuff // class TrayActionItemListener implements ItemListener { @Override public void itemStateChanged(ItemEvent e) { try { Configuration config = ltSupport.getConfig(); if (e.getStateChange() == ItemEvent.SELECTED) { config.setRunServer(true); boolean serverStarted = maybeStartServer(); enableHttpServerItem.setState(serverStarted); config.setRunServer(serverStarted); config.saveConfiguration(ltSupport.getLanguage()); } else if (e.getStateChange() == ItemEvent.DESELECTED) { config.setRunServer(false); config.saveConfiguration(ltSupport.getLanguage()); stopServer(); } } catch (IOException ex) { Tools.showError(ex); } } } class TrayActionRMBListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { if (isCommand(e, "guiMenuCheckClipboard")) { restoreFromTrayAndCheck(); } else if (isCommand(e, "guiMenuShowMainWindow")) { restoreFromTray(); } else if (isCommand(e, "guiMenuQuit")) { quit(); } else { JOptionPane.showMessageDialog(null, "Unknown action: " + e.getActionCommand(), "Error", JOptionPane.ERROR_MESSAGE); } } private boolean isCommand(ActionEvent e, String label) { return e.getActionCommand().equalsIgnoreCase(Tools.getLabel(messages.getString(label))); } } class TrayActionListener extends MouseAdapter { @Override public void mouseClicked(@SuppressWarnings("unused")MouseEvent e) { if (frame.isVisible() && frame.isActive()) { frame.setVisible(false); } else if (frame.isVisible() && !frame.isActive()) { frame.toFront(); restoreFromTrayAndCheck(); } else { restoreFromTrayAndCheck(); } } } class CloseListener extends WindowAdapter { @Override public void windowClosing(@SuppressWarnings("unused")WindowEvent e) { quitOrHide(); } } static class PlainTextFileFilter extends FileFilter { @Override public boolean accept(File f) { boolean isTextFile = f.getName().toLowerCase().endsWith(".txt"); return isTextFile || f.isDirectory(); } @Override public String getDescription() { return "*.txt"; } } class OpenAction extends AbstractAction { OpenAction() { super(getLabel("guiMenuOpen")); putValue(Action.SHORT_DESCRIPTION, messages.getString("guiMenuOpenShortDesc")); putValue(Action.LONG_DESCRIPTION, messages.getString("guiMenuOpenLongDesc")); putValue(Action.MNEMONIC_KEY, getMnemonic("guiMenuOpen")); putValue(Action.ACCELERATOR_KEY, getMenuKeyStroke(KeyEvent.VK_O)); putValue(Action.SMALL_ICON, getImageIcon("sc_open.png")); putValue(Action.LARGE_ICON_KEY, getImageIcon("lc_open.png")); } @Override public void actionPerformed(ActionEvent e) { loadFile(); } } class SaveAction extends AbstractAction { SaveAction() { super(getLabel("guiMenuSave")); putValue(Action.SHORT_DESCRIPTION, messages.getString("guiMenuSaveShortDesc")); putValue(Action.LONG_DESCRIPTION, messages.getString("guiMenuSaveLongDesc")); putValue(Action.MNEMONIC_KEY, getMnemonic("guiMenuSave")); putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); putValue(Action.SMALL_ICON, getImageIcon("sc_save.png")); putValue(Action.LARGE_ICON_KEY, getImageIcon("lc_save.png")); } @Override public void actionPerformed(ActionEvent e) { saveFile(false); } } class SaveAsAction extends AbstractAction { SaveAsAction() { super(getLabel("guiMenuSaveAs")); putValue(Action.SHORT_DESCRIPTION, messages.getString("guiMenuSaveAsShortDesc")); putValue(Action.LONG_DESCRIPTION, messages.getString("guiMenuSaveAsLongDesc")); putValue(Action.MNEMONIC_KEY, getMnemonic("guiMenuSaveAs")); putValue(Action.SMALL_ICON, getImageIcon("sc_saveas.png")); putValue(Action.LARGE_ICON_KEY, getImageIcon("lc_saveas.png")); } @Override public void actionPerformed(ActionEvent e) { saveFile(true); } } class CheckClipboardAction extends AbstractAction { CheckClipboardAction() { super(getLabel("guiMenuCheckClipboard")); putValue(Action.MNEMONIC_KEY, getMnemonic("guiMenuCheckClipboard")); putValue(Action.ACCELERATOR_KEY, getMenuKeyStroke(KeyEvent.VK_Y)); } @Override public void actionPerformed(ActionEvent e) { checkClipboardText(); } } class TagTextAction extends AbstractAction { TagTextAction() { super(getLabel("guiTagText")); putValue(Action.MNEMONIC_KEY, getMnemonic("guiTagText")); putValue(Action.ACCELERATOR_KEY, getMenuKeyStroke(KeyEvent.VK_T)); } @Override public void actionPerformed(ActionEvent e) { tagText(); } } class AddRulesAction extends AbstractAction { AddRulesAction() { super(getLabel("guiMenuAddRules")); putValue(Action.MNEMONIC_KEY, getMnemonic("guiMenuAddRules")); } @Override public void actionPerformed(ActionEvent e) { try { addLanguage(); } catch (Exception ex) { Tools.showError(ex); } } } class OptionsAction extends AbstractAction { OptionsAction() { super(getLabel("guiMenuOptions")); putValue(Action.MNEMONIC_KEY, getMnemonic("guiMenuOptions")); putValue(Action.ACCELERATOR_KEY, getMenuKeyStroke(KeyEvent.VK_S)); } @Override public void actionPerformed(ActionEvent e) { showOptions(); } } class SelectFontAction extends AbstractAction { SelectFontAction() { super(getLabel("guiSelectFont")); } @Override public void actionPerformed(ActionEvent e) { showSelectFontDialog(); } } class SelectLFAction extends AbstractAction { private final UIManager.LookAndFeelInfo lf; SelectLFAction(UIManager.LookAndFeelInfo lf) { super(lf.getName()); this.lf = lf; } @Override public void actionPerformed(ActionEvent e) { try { UIManager.setLookAndFeel(lf.getClassName()); SwingUtilities.updateComponentTreeUI(frame); frame.pack(); ltSupport.getConfig().setLookAndFeelName(lf.getName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { Tools.showError(ex); } } } class HideAction extends AbstractAction { HideAction() { super(getLabel("guiMenuHide")); putValue(Action.MNEMONIC_KEY, getMnemonic("guiMenuHide")); putValue(Action.ACCELERATOR_KEY, getMenuKeyStroke(KeyEvent.VK_D)); } @Override public void actionPerformed(ActionEvent e) { hideToTray(); } } class QuitAction extends AbstractAction { QuitAction() { super(getLabel("guiMenuQuit")); putValue(Action.MNEMONIC_KEY, getMnemonic("guiMenuQuit")); putValue(Action.ACCELERATOR_KEY, getMenuKeyStroke(KeyEvent.VK_Q)); } @Override public void actionPerformed(ActionEvent e) { quit(); } } class AboutAction extends AbstractAction { AboutAction() { super(getLabel("guiMenuAbout")); putValue(Action.MNEMONIC_KEY, getMnemonic("guiMenuAbout")); } @Override public void actionPerformed(ActionEvent e) { AboutDialog about = new AboutDialog(messages, getFrame()); about.show(); } } class CheckAction extends AbstractAction { CheckAction() { super(getLabel("checkText")); putValue(Action.SHORT_DESCRIPTION, messages.getString("checkTextShortDesc")); putValue(Action.LONG_DESCRIPTION, messages.getString("checkTextLongDesc")); putValue(Action.MNEMONIC_KEY, getMnemonic("checkText")); putValue(Action.SMALL_ICON, getImageIcon("sc_spelldialog.png")); putValue(Action.LARGE_ICON_KEY, getImageIcon("lc_spelldialog.png")); } @Override public void actionPerformed(ActionEvent e) { checkTextAndDisplayResults(); } } class AutoCheckAction extends AbstractAction { private boolean enable; AutoCheckAction(boolean initial) { super(getLabel("autoCheckText")); putValue(Action.SHORT_DESCRIPTION, messages.getString("autoCheckTextShortDesc")); putValue(Action.LONG_DESCRIPTION, messages.getString("autoCheckTextLongDesc")); putValue(Action.MNEMONIC_KEY, getMnemonic("autoCheckText")); putValue(Action.SMALL_ICON, getImageIcon("sc_spellonline.png")); putValue(Action.LARGE_ICON_KEY, getImageIcon("lc_spellonline.png")); enable = initial; putValue(Action.SELECTED_KEY, enable); } @Override public void actionPerformed(ActionEvent e) { enable = !enable; putValue(Action.SELECTED_KEY, enable); ltSupport.setBackgroundCheckEnabled(enable); } } class ClearTextAction extends AbstractAction { ClearTextAction() { super(getLabel("clearText")); putValue(Action.SHORT_DESCRIPTION, messages.getString("clearText")); putValue(Action.SMALL_ICON, getImageIcon("sc_closedoc.png")); putValue(Action.LARGE_ICON_KEY, getImageIcon("lc_closedoc.png")); } @Override public void actionPerformed(ActionEvent e) { ltSupport.getTextComponent().setText(""); } } private class SelectAllAction extends TextAction { private SelectAllAction() { super(getLabel("guiMenuSelectAll")); putValue(Action.MNEMONIC_KEY, KeyEvent.VK_A); } @Override public void actionPerformed(ActionEvent e) { JTextComponent component = getFocusedComponent(); component.selectAll(); } } class RecentFileAction extends AbstractAction { private final File file; RecentFileAction(File file) { super(file.getName()); this.file = file; putValue(Action.SHORT_DESCRIPTION, file.getAbsolutePath()); } @Override public void actionPerformed(ActionEvent e) { if(file.exists()) { loadFile(file); } else { JOptionPane.showMessageDialog(frame, messages.getString("guiFileNotFound"), messages.getString("dialogTitleError"), JOptionPane.ERROR_MESSAGE); recentFiles.remove(file.getAbsolutePath()); updateRecentFilesMenu(); } } } class ShowResultAction extends AbstractAction { private boolean enable; ShowResultAction(boolean initial) { super(getLabel("guiShowResultArea")); putValue(Action.SHORT_DESCRIPTION, messages.getString("guiShowResultArea")); putValue(Action.LONG_DESCRIPTION, messages.getString("guiShowResultArea")); putValue(Action.MNEMONIC_KEY, getMnemonic("guiShowResultArea")); enable = initial; putValue(Action.SELECTED_KEY, enable); } @Override public void actionPerformed(ActionEvent e) { enable = !enable; putValue(Action.SELECTED_KEY, enable); setResultAreaVisible(enable); } } private ImageIcon getImageIcon(String filename) { Image image = Toolkit.getDefaultToolkit().getImage( JLanguageTool.getDataBroker().getFromResourceDirAsUrl(filename)); return new ImageIcon(image); } private ConfigurationDialog getCurrentConfigDialog() { Language language = ltSupport.getLanguage(); ConfigurationDialog configDialog; if (configDialogs.containsKey(language)) { configDialog = configDialogs.get(language); } else { configDialog = new ConfigurationDialog(frame, false, ltSupport.getConfig()); configDialog.addExtraPanel(new GuiLangConfigPanel(messages, localStorage)); configDialogs.put(language, configDialog); } return configDialog; } }