HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

A simple Python IDE in Java Swing

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
simplejavaswingpythonide

Problem

I've made an IDE in Java, using swing. It uses a couple of resources (prefs.json and help.txt) and some imported .jar files for reading the JSON. I know the code's quite long, but the answer doesn't have to be a very detailed one.

```
package io.j4cobgarby.github;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;

import javax.swing.AbstractAction;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;

import org.json.JSONException;
import org.json.JSONObject;

public class Main {

private JFrame frame;
private JTextField textField;

public static String currentFile = null;
private static java.util.Scanner scanner;
private JTextField cmd2Run;

JSONObject prefs = null;

String osType = "Unknown";

static JTextArea area = new JTextArea();

static JLabel filenameLabel = new JLabel("");
private JTextField status;

/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run()

Solution

Don't put everything in Main

Main window = new Main();


This is a different approach. Usually Main exists only to hold the main method. There's no point in instantiating it. That's why it's often separate, so that you can put main separately from the application classes. It often has helper methods, but they usually do things related to input and output to make main simpler. The application itself would be in other classes.

I think that if I were writing this, I'd say something like

IdeGui window = new IdeGui();


Then all that constructor code could be in something called IdeGui or GUI that could be reused. And all the business logic methods could be in another class, IdeApplication, IdeFileManager, or similar.

Access level

private static java.util.Scanner scanner;


This is only used in one method and you remake it every time the method is called. Why is it an object field? It could just be a local variable.

public static String currentFile = null;


Why is this public? Everything is in one class. You could make everything private just as well. My rule of thumb is to make everything private until I have a reason to give it a more accessible level.

I have the same issue with the package-protected (default access level) members.

Don't save extra variables

runPython((osType == "win") ? pyCommandWin : pyCommandUnix);


This could be

runPython(pyCommand);


with

String pyCommandWin = (String) prefs.get("pyCommandWin");
        String pyCommandUnix = (String) prefs.get("pyCommandUnix");


changed to

String pyCommand = (String)prefs.get((osType == "win") ? "pyCommandWin" : "pyCommandUnix");


Then you don't have this extra variable that you never use floating around. Also, if you add a third command format, this way you only make the change in one place. You can just change the way that pyCommand is set. Running it stays exactly the same.

Parallel logic is risky. It's easy to forget to make a change in one place or the other.

try-with-resources

FileWriter fwrite = null;
        try {
            fwrite = new FileWriter(new File(saveTo), false);
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        try {
            fwrite.write(area.getText());
            fwrite.close();
        } catch (IOException e1) {
            e1.printStackTrace();
        }


If there is an exception in the first block, you could end up trying to write to and close a null in the second block. Or an exception on writing might keep the close from being reached.

try (FileWriter fwrite = new FileWriter(new File(saveTo), false)) {
            fwrite.write(area.getText());
        } catch (IOException e1) {
            e1.printStackTrace();
        }


Now we only write if the file can be opened and we let the try-with-resources handle closing. So the close always happens.

Code Snippets

Main window = new Main();
IdeGui window = new IdeGui();
private static java.util.Scanner scanner;
public static String currentFile = null;
runPython((osType == "win") ? pyCommandWin : pyCommandUnix);

Context

StackExchange Code Review Q#141024, answer score: 4

Revisions (0)

No revisions yet.