1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle.gui;
21
22 import java.awt.BorderLayout;
23 import java.awt.FlowLayout;
24 import java.awt.GridLayout;
25 import java.awt.Toolkit;
26 import java.awt.event.ActionEvent;
27 import java.awt.event.KeyEvent;
28 import java.io.File;
29 import java.io.Serial;
30
31 import javax.swing.AbstractAction;
32 import javax.swing.BorderFactory;
33 import javax.swing.JButton;
34 import javax.swing.JComboBox;
35 import javax.swing.JFileChooser;
36 import javax.swing.JFrame;
37 import javax.swing.JLabel;
38 import javax.swing.JOptionPane;
39 import javax.swing.JPanel;
40 import javax.swing.JScrollPane;
41 import javax.swing.JSplitPane;
42 import javax.swing.JTextArea;
43 import javax.swing.SwingConstants;
44 import javax.swing.border.Border;
45 import javax.swing.filechooser.FileFilter;
46
47 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
48 import com.puppycrawl.tools.checkstyle.gui.MainFrameModel.ParseMode;
49
50
51
52
53
54
55
56
57
58 public class MainFrame extends JFrame {
59
60
61 @Serial
62 private static final long serialVersionUID = 7970053543351871890L;
63
64
65 private static final String ICON = "icon.png";
66
67
68 private final transient MainFrameModel model = new MainFrameModel();
69
70 private final ReloadAction reloadAction = new ReloadAction();
71
72 private JTextArea textArea;
73
74 private JTextArea xpathTextArea;
75
76 private TreeTable treeTable;
77
78
79 public MainFrame() {
80 createContent();
81 }
82
83
84 private void createContent() {
85 setLayout(new BorderLayout());
86 setIconImage(Toolkit.getDefaultToolkit().getImage(MainFrame.class.getResource(ICON)));
87
88 textArea = new JTextArea(20, 15);
89 textArea.setEditable(false);
90 final JScrollPane textAreaScrollPane = new JScrollPane(textArea);
91 final JPanel textAreaPanel = new JPanel();
92 textAreaPanel.setLayout(new BorderLayout());
93 textAreaPanel.add(textAreaScrollPane);
94 textAreaPanel.add(createButtonsPanel(), BorderLayout.PAGE_END);
95
96 treeTable = new TreeTable(model.getParseTreeTableModel());
97 treeTable.setEditor(textArea);
98 treeTable.setLinePositionList(model.getLinesToPosition());
99 final JScrollPane treeTableScrollPane = new JScrollPane(treeTable);
100
101 final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
102 treeTableScrollPane, textAreaPanel);
103
104 add(splitPane, BorderLayout.CENTER);
105 splitPane.setResizeWeight(0.7);
106
107 xpathTextArea = new JTextArea("Xpath", 7, 0);
108 xpathTextArea.setName("xpathTextArea");
109 xpathTextArea.setVisible(false);
110 final JPanel xpathAreaPanel = new JPanel();
111 xpathAreaPanel.setLayout(new BorderLayout());
112 xpathAreaPanel.add(xpathTextArea);
113 xpathAreaPanel.add(createXpathButtonsPanel(), BorderLayout.PAGE_END);
114
115 treeTable.setXpathEditor(xpathTextArea);
116
117 final Border title = BorderFactory.createTitledBorder("Xpath Query");
118 xpathAreaPanel.setBorder(title);
119
120 add(xpathAreaPanel, BorderLayout.PAGE_END);
121 }
122
123
124
125
126
127
128 private JPanel createButtonsPanel() {
129 final JButton openFileButton = new JButton(new FileSelectionAction());
130 openFileButton.setName("openFileButton");
131 openFileButton.setMnemonic(KeyEvent.VK_O);
132 openFileButton.setText("Open File");
133
134 reloadAction.setEnabled(false);
135 final JButton reloadFileButton = new JButton(reloadAction);
136 reloadFileButton.setMnemonic(KeyEvent.VK_R);
137 reloadFileButton.setText("Reload File");
138
139 final JComboBox<ParseMode> modesCombobox = new JComboBox<>(ParseMode.values());
140 modesCombobox.setName("modesCombobox");
141 modesCombobox.setSelectedIndex(0);
142 modesCombobox.addActionListener(event -> {
143 model.setParseMode((ParseMode) modesCombobox.getSelectedItem());
144 reloadAction.actionPerformed(null);
145 });
146
147 final JLabel modesLabel = new JLabel("Modes:", SwingConstants.RIGHT);
148 final int leftIndentation = 10;
149 modesLabel.setBorder(BorderFactory.createEmptyBorder(0, leftIndentation, 0, 0));
150 modesLabel.setDisplayedMnemonic(KeyEvent.VK_M);
151 modesLabel.setLabelFor(modesCombobox);
152
153 final JPanel buttonPanel = new JPanel();
154 buttonPanel.setLayout(new GridLayout(1, 2));
155 buttonPanel.add(openFileButton);
156 buttonPanel.add(reloadFileButton);
157
158 final JPanel modesPanel = new JPanel();
159 modesPanel.add(modesLabel);
160 modesPanel.add(modesCombobox);
161
162 final JPanel mainPanel = new JPanel();
163 mainPanel.setLayout(new BorderLayout());
164 mainPanel.add(buttonPanel);
165 mainPanel.add(modesPanel, BorderLayout.LINE_END);
166
167 return mainPanel;
168 }
169
170
171
172
173
174
175 private JPanel createXpathButtonsPanel() {
176 final JButton expandButton = new JButton(new ExpandCollapseAction());
177 expandButton.setName("expandButton");
178 expandButton.setText("Expand/Collapse");
179
180 final JButton findNodeButton = new JButton(new FindNodeByXpathAction());
181 findNodeButton.setName("findNodeButton");
182 findNodeButton.setText("Find node by Xpath");
183
184 final JPanel xpathButtonsPanel = new JPanel();
185 xpathButtonsPanel.setLayout(new FlowLayout());
186 xpathButtonsPanel.add(expandButton);
187 xpathButtonsPanel.add(findNodeButton);
188
189 final JPanel mainPanel = new JPanel();
190 mainPanel.setLayout(new BorderLayout());
191 mainPanel.add(xpathButtonsPanel, BorderLayout.LINE_START);
192
193 return mainPanel;
194 }
195
196
197
198
199
200
201 public void openFile(File sourceFile) {
202 try {
203 model.openFile(sourceFile);
204 setTitle(model.getTitle());
205 reloadAction.setEnabled(model.isReloadActionEnabled());
206 textArea.setText(model.getText());
207 treeTable.setLinePositionList(model.getLinesToPosition());
208 }
209 catch (final CheckstyleException exc) {
210 JOptionPane.showMessageDialog(this, exc.getMessage());
211 }
212 }
213
214
215
216
217 private final class FileSelectionAction extends AbstractAction {
218
219
220 @Serial
221 private static final long serialVersionUID = 1762396148873280589L;
222
223 @Override
224 public void actionPerformed(ActionEvent event) {
225 final JFileChooser fileChooser = new JFileChooser(model.getLastDirectory());
226 final FileFilter filter = new JavaFileFilter();
227 fileChooser.setFileFilter(filter);
228
229 final int returnCode = fileChooser.showOpenDialog(MainFrame.this);
230 if (returnCode == JFileChooser.APPROVE_OPTION) {
231 final File file = fileChooser.getSelectedFile();
232 openFile(file);
233 }
234 }
235
236 }
237
238
239
240
241 private final class ReloadAction extends AbstractAction {
242
243
244 @Serial
245 private static final long serialVersionUID = -890320994114628011L;
246
247 @Override
248 public void actionPerformed(ActionEvent event) {
249 openFile(model.getCurrentFile());
250 }
251
252 }
253
254
255
256
257 private final class ExpandCollapseAction extends AbstractAction {
258
259
260 @Serial
261 private static final long serialVersionUID = -890320994114628011L;
262
263 @Override
264 public void actionPerformed(ActionEvent event) {
265 xpathTextArea.setVisible(!xpathTextArea.isVisible());
266 }
267
268 }
269
270
271
272
273 private final class FindNodeByXpathAction extends AbstractAction {
274
275
276 @Serial
277 private static final long serialVersionUID = -890320994114628011L;
278
279 @Override
280 public void actionPerformed(ActionEvent event) {
281 treeTable.selectNodeByXpath();
282 }
283
284 }
285
286
287
288
289 private static final class JavaFileFilter extends FileFilter {
290
291 @Override
292 public boolean accept(File file) {
293 return MainFrameModel.shouldAcceptFile(file);
294 }
295
296 @Override
297 public String getDescription() {
298 return "Java Source File";
299 }
300
301 }
302
303 }