001////////////////////////////////////////////////////////////////////////////////
002// checkstyle: Checks Java source code for adherence to a set of rules.
003// Copyright (C) 2001-2016 the original author or authors.
004//
005// This library is free software; you can redistribute it and/or
006// modify it under the terms of the GNU Lesser General Public
007// License as published by the Free Software Foundation; either
008// version 2.1 of the License, or (at your option) any later version.
009//
010// This library is distributed in the hope that it will be useful,
011// but WITHOUT ANY WARRANTY; without even the implied warranty of
012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013// Lesser General Public License for more details.
014//
015// You should have received a copy of the GNU Lesser General Public
016// License along with this library; if not, write to the Free Software
017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018////////////////////////////////////////////////////////////////////////////////
019
020package com.puppycrawl.tools.checkstyle.gui;
021
022import java.awt.BorderLayout;
023import java.awt.GridLayout;
024import java.awt.event.ActionEvent;
025import java.awt.event.KeyEvent;
026import java.io.File;
027
028import javax.swing.AbstractAction;
029import javax.swing.JButton;
030import javax.swing.JFileChooser;
031import javax.swing.JFrame;
032import javax.swing.JOptionPane;
033import javax.swing.JPanel;
034import javax.swing.JScrollPane;
035import javax.swing.JSplitPane;
036import javax.swing.JTextArea;
037import javax.swing.filechooser.FileFilter;
038
039import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
040
041/**
042 * Displays information about a parse tree.
043 * The user can change the file that is parsed and displayed
044 * using a JFileChooser.
045 *
046 * @author Lars Kühne
047 * @author Vladislav Lisetskiy
048 */
049public class MainFrame extends JFrame {
050
051    private static final long serialVersionUID = 7970053543351871890L;
052    /** Checkstyle frame model. */
053    private final transient MainFrameModel model = new MainFrameModel();
054    /** Reload action. */
055    private final ReloadAction reloadAction = new ReloadAction();
056    /** Code text area. */
057    private JTextArea textArea;
058    /** Tree table. */
059    private JTreeTable treeTable;
060
061    /** Create a new MainFrame. */
062    public MainFrame() {
063        createContent();
064    }
065
066    /** Create content of this MainFrame. */
067    private void createContent() {
068        setLayout(new BorderLayout());
069
070        textArea = new JTextArea(20, 15);
071        textArea.setEditable(false);
072        final JScrollPane textAreaScrollPane = new JScrollPane(textArea);
073
074        treeTable = new JTreeTable(model.getParseTreeTableModel());
075        treeTable.setEditor(textArea);
076        treeTable.setLinePositionMap(model.getLinesToPosition());
077        final JScrollPane treeTableScrollPane = new JScrollPane(treeTable);
078
079        final JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, treeTableScrollPane,
080            textAreaScrollPane);
081        add(splitPane, BorderLayout.CENTER);
082        splitPane.setResizeWeight(0.7);
083
084        add(createButtonsPanel(), BorderLayout.PAGE_END);
085
086        pack();
087    }
088
089    /**
090     * Create buttons panel.
091     * @return buttons panel.
092     */
093    private JPanel createButtonsPanel() {
094        final JButton openFileButton = new JButton(new FileSelectionAction());
095        openFileButton.setMnemonic(KeyEvent.VK_S);
096        openFileButton.setText("Open File");
097
098        reloadAction.setEnabled(false);
099        final JButton reloadFileButton = new JButton(reloadAction);
100        reloadFileButton.setMnemonic(KeyEvent.VK_R);
101        reloadFileButton.setText("Reload File");
102
103        final JPanel buttonPanel = new JPanel();
104        buttonPanel.setLayout(new GridLayout(1, 2));
105        buttonPanel.add(openFileButton);
106        buttonPanel.add(reloadFileButton);
107
108        return buttonPanel;
109    }
110
111    /**
112     * Open file and load it.
113     * @param sourceFile the file to open.
114     */
115    public void openFile(File sourceFile) {
116        try {
117            model.openFile(sourceFile);
118            setTitle(model.getTitle());
119            reloadAction.setEnabled(model.isReloadActionEnabled());
120            textArea.setText(model.getText());
121            treeTable.setLinePositionMap(model.getLinesToPosition());
122        }
123        catch (final CheckstyleException ex) {
124            JOptionPane.showMessageDialog(this, ex.getMessage());
125        }
126    }
127
128    /**
129     * Handler for file selection action events.
130     */
131    private class FileSelectionAction extends AbstractAction {
132        private static final long serialVersionUID = 1762396148873280589L;
133
134        @Override
135        public void actionPerformed(ActionEvent event) {
136            final JFileChooser fileChooser = new JFileChooser(model.getLastDirectory());
137            final FileFilter filter = new JavaFileFilter();
138            fileChooser.setFileFilter(filter);
139
140            final int returnCode = fileChooser.showOpenDialog(MainFrame.this);
141            if (returnCode == JFileChooser.APPROVE_OPTION) {
142                final File file = fileChooser.getSelectedFile();
143                openFile(file);
144            }
145        }
146    }
147
148    /**
149     * Handler for reload action events.
150     */
151    private class ReloadAction extends AbstractAction {
152        private static final long serialVersionUID = -890320994114628011L;
153
154        @Override
155        public void actionPerformed(ActionEvent event) {
156            openFile(model.getCurrentFile());
157        }
158    }
159
160    /**
161     * Filter for Java files.
162     */
163    private static class JavaFileFilter extends FileFilter {
164        @Override
165        public boolean accept(File file) {
166            return MainFrameModel.shouldAcceptFile(file);
167        }
168
169        @Override
170        public String getDescription() {
171            return "Java Source File";
172        }
173    }
174}