如何在复杂的gui应用程序中管理类体系结构

时间:2016-02-09 12:27:55

标签: java swing user-interface

我正在编写一个需要大量swing GUI组件的应用程序。

当我将内部类事件处理程序放在单独的文件中时,我无法访问主类的组件。

我在组织课程时遇到了很多麻烦。有没有一种方法来组织和整齐地布局类架构?

另外,我有很多匿名和内部类,我的主要课程变得臃肿。

如何管理我的gui类,以便以一种可以调用其他应用程序类对象的方式轻松处理事件

public class MainScreen extends JFrame {

    // Variables declaration                     
    private JTree fileTree;
    private JScrollPane fileTreeScroll;
    private JSplitPane horSplit;
    private JTabbedPane textAreaPane;
    private JTabbedPane outputPane;
    private JSplitPane mainSplit;
    private JEditorPane textEditor;
    private JScrollPane textScroll;
    private JLabel log;

    private Controller controller;
    private String projectName;

    public static final String APP_NAME = "Smart Coder";
    public static final String IMAGE_PATH = "/ImageResources/";
    public static final int maxWidth = 1280;
    public static final int maxHeight = 720;
    public static final int minWidth = 800;
    public static final int minHeight = 450;
    public static final int divLen = 300;
    public static final int divLen2 = 150;

    protected JTextArea editor;
    javax.swing.JFrame frame;
    protected JFileChooser fileChooser;
    protected File currentFile;

    protected boolean textChanged = false;
    protected JToolBar toolBar;

    // End of variables declaration 
    public MainScreen() {
        super(APP_NAME);
        setSize(minWidth, minHeight);
        //DefaultSyntaxKit.initKit();
        jsyntaxpane.DefaultSyntaxKit.initKit();

        controller = new Controller();

        ///////////////////////////////////////////////////////////
        mainSplit = new JSplitPane();
        outputPane = new JTabbedPane();
        horSplit = new JSplitPane();
        fileTreeScroll = new JScrollPane();
        fileTree = new JTree();
        textAreaPane = new JTabbedPane();
        textScroll = new JScrollPane();
        textEditor = new JEditorPane();
        log = new JLabel("Status : ");

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setMaximumSize(new java.awt.Dimension(maxWidth, maxHeight));
        setMinimumSize(new java.awt.Dimension(minWidth, minHeight));

        mainSplit.setDividerLocation(divLen);
        mainSplit.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        mainSplit.setToolTipText("Drag to change size.");
        mainSplit.setBottomComponent(outputPane);
        horSplit.setDividerLocation(divLen2);

        fileTreeScroll.setViewportView(fileTree);

        horSplit.setLeftComponent(fileTreeScroll);

        horSplit.setRightComponent(textAreaPane);

        mainSplit.setLeftComponent(horSplit);

        //////////////////////////////////////////////////////////////////////////////
        editor = new JTextArea();
        textScroll.add(editor);

        JMenuBar menuBar = createMenuBar();
        setJMenuBar(menuBar);
        getContentPane().add(log, BorderLayout.SOUTH);

        fileChooser = new JFileChooser();
        try {
            File dir = (new File(".")).getCanonicalFile();
            fileChooser.setCurrentDirectory(dir);
        } catch (IOException ex) {
        }

        updateEditor();
        //newDocument();

        WindowListener wndCloser = new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("Action event of window closing.");
                if (!promptToSave()) {
                    return;
                }
                System.exit(0);
            }
        };

        addWindowListener(wndCloser);
        getContentPane().add(mainSplit);
        frame = this;
        pack();
    }

    protected JMenuBar createMenuBar() {
        final JMenuBar menuBar = new JMenuBar();
        JMenu fileMenu = new JMenu("File");
        fileMenu.setMnemonic('f');

//        JMenu newMenu = new JMenu("New");
//        newMenu.setMnemonic('n');
        // Action for New Project
        ImageIcon iconNewPro = new ImageIcon(getClass().getResource(IMAGE_PATH + "newpack.png"));
        Action actionNewProject = new MyAction("New Project", iconNewPro, KeyEvent.VK_P,
                KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK + InputEvent.SHIFT_MASK));
        fileMenu.add(actionNewProject);
//        newMenu.add(actionNewProject);

        // Action for New File
        ImageIcon iconNewFile = new ImageIcon(getClass().getResource(IMAGE_PATH + "new.png"));
        Action actionNew = new MyAction("New Java File", iconNewFile, KeyEvent.VK_J, KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK));
        fileMenu.add(actionNew);
//        newMenu.add(actionNew);

//        fileMenu.add(newMenu);
        // Action for Open Project
        ImageIcon iconOpen = new ImageIcon(getClass().getResource(IMAGE_PATH + "openpack.png"));
        Action actionOpen = new MyAction("Open", iconOpen, KeyEvent.VK_O,
                KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
        fileMenu.add(actionOpen);

        // Action for Save Project
        ImageIcon iconSave = new ImageIcon(getClass().getResource(IMAGE_PATH + "save.png"));
        Action actionSave = new MyAction("Save", iconSave, KeyEvent.VK_S,
                KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK));
        fileMenu.add(actionSave);
        fileMenu.addSeparator();

        // Action for Exit Project
        ImageIcon iconExit = new ImageIcon(getClass().getResource(IMAGE_PATH + "exit.png"));
        Action actionExit = new MyAction("Exit", iconExit, KeyEvent.VK_X,
                KeyStroke.getKeyStroke(KeyEvent.VK_F4, InputEvent.ALT_MASK));
        fileMenu.add(actionExit);
        menuBar.add(fileMenu);

        // Edit menu starts 
        JMenu editMenu = new JMenu("Edit");
        editMenu.setMnemonic('e');

        // undo action
        ImageIcon iconUndo = new ImageIcon(getClass().getResource(IMAGE_PATH + "undo.png"));
        Action actionUndo = new MyAction("Undo", iconUndo, KeyEvent.VK_U,
                KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_MASK));
        editMenu.add(actionUndo);

        // redo action
        ImageIcon iconRedo = new ImageIcon(getClass().getResource(IMAGE_PATH + "redo.png"));
        Action actionRedo = new MyAction("Redo", iconRedo, KeyEvent.VK_R,
                KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_MASK));
        editMenu.add(actionRedo);
        editMenu.addSeparator();

        // cut action
        ImageIcon iconCut = new ImageIcon(getClass().getResource(IMAGE_PATH + "cut.png"));
        Action actionCut = new MyAction("Cut", iconCut, KeyEvent.VK_X,
                KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK));
        editMenu.add(actionCut);

        // copy action
        ImageIcon iconCopy = new ImageIcon(getClass().getResource(IMAGE_PATH + "copy.png"));
        Action actionCopy = new MyAction("Copy", iconCopy, KeyEvent.VK_C,
                KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK));
        editMenu.add(actionCopy);

        // paste action
        ImageIcon iconPaste = new ImageIcon(getClass().getResource(IMAGE_PATH + "paste.png"));
        Action actionPaste = new MyAction("Paste", iconPaste, KeyEvent.VK_V,
                KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK));
        editMenu.add(actionPaste);
        editMenu.addSeparator();

        // find action
        ImageIcon iconFind = new ImageIcon(getClass().getResource(IMAGE_PATH + "find.png"));
        Action actionFind = new MyAction("Find", iconFind, KeyEvent.VK_F,
                KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_MASK));
        editMenu.add(actionFind);

        // Replace action
        ImageIcon iconReplace = new ImageIcon(getClass().getResource(IMAGE_PATH + "findreplace.png"));
        Action actionReplace = new MyAction("Replace", iconReplace, KeyEvent.VK_R,
                KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_MASK + InputEvent.SHIFT_MASK));
        editMenu.add(actionReplace);

        menuBar.add(editMenu);

        // Run menu starts 
        JMenu runMenu = new JMenu("Run");
        runMenu.setMnemonic('r');

        ImageIcon iconRun = new ImageIcon(getClass().getResource(IMAGE_PATH + "play.png"));
        Action actionRun = new MyAction("Run", iconRun, KeyEvent.VK_R,
                KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_MASK));
        runMenu.add(actionRun);

        menuBar.add(runMenu);

        // Create toolbar
        toolBar = new JToolBar("File Commands");
        JButton bNewPro = toolBar.add(actionNewProject);
        bNewPro.setToolTipText("New Project");

        JButton bNew = toolBar.add(actionNew);
        bNew.setToolTipText("New Java File");

        JButton bOpen = toolBar.add(actionOpen);
        bOpen.setToolTipText("Open Project");

        JButton bSave = toolBar.add(actionSave);
        bSave.setToolTipText("Save file");

        getContentPane().add(toolBar, BorderLayout.NORTH);
        return menuBar;
    }

    protected String getDocumentName() {
        return currentFile == null ? "Untitled"
                : currentFile.getName();
    }

    protected void newDocument() {
        editor.setText("");
        currentFile = null;
        setTitle(APP_NAME + " [" + getDocumentName() + "]");
        textChanged = false;
        editor.getDocument().addDocumentListener(new UpdateListener());
    }

    protected void openDocument() {
        if (fileChooser.showOpenDialog(MainScreen.this)
                != JFileChooser.APPROVE_OPTION) {
            return;
        }
        File f = fileChooser.getSelectedFile();
        if (f == null || !f.isFile()) {
            return;
        }
        currentFile = f;
        try {
            FileReader in = new FileReader(currentFile);
            editor.read(in, null);
            in.close();
            setTitle(APP_NAME + " [" + getDocumentName() + "]");
        } catch (IOException ex) {
            showError(ex, "Error reading file " + currentFile);
        }
        textChanged = false;
        editor.getDocument().addDocumentListener(new UpdateListener());
    }

    protected boolean saveFile() {
        if (currentFile == null) {
            if (fileChooser.showSaveDialog(MainScreen.this)
                    != JFileChooser.APPROVE_OPTION) {
                return false;
            }
            File f = fileChooser.getSelectedFile();
            if (f == null) {
                return false;
            }
            currentFile = f;
            setTitle(APP_NAME + " [" + getDocumentName() + "]");
        }

        try {
            FileWriter out = new FileWriter(currentFile);
            editor.write(out);
            out.close();
        } catch (IOException ex) {
            showError(ex, "Error saving file " + currentFile);
            return false;
        }
        textChanged = false;
        return true;
    }

    protected boolean promptToSave() {
        if (!textChanged) {
            return true;
        }
        int result = JOptionPane.showConfirmDialog(this,
                "Save changes to " + getDocumentName() + "?",
                APP_NAME, JOptionPane.YES_NO_CANCEL_OPTION,
                JOptionPane.INFORMATION_MESSAGE);
        switch (result) {
            case JOptionPane.YES_OPTION:
                if (!saveFile()) {
                    return false;
                }
                return true;
            case JOptionPane.NO_OPTION:
                return true;
            case JOptionPane.CANCEL_OPTION:
                return false;
        }
        return true;
    }

    protected void updateEditor() {
        editor.repaint();
    }

    public void showError(Exception ex, String message) {
        ex.printStackTrace();
        JOptionPane.showMessageDialog(this,
                message, APP_NAME,
                JOptionPane.WARNING_MESSAGE);
    }

    public void disableAll() {
        fileTree.setEnabled(false);
        fileTreeScroll.setEnabled(false);
        textAreaPane.setEnabled(false);
        outputPane.setEnabled(false);
        textEditor.setEnabled(false);
    }

    public void showNewProDialog() {
        System.out.println("Action event of New Project button.");
        NewProject dialogPro = new NewProject(frame, true);
        System.out.println(dialogPro.getSize());
        dialogPro.setVisible(true);
        if (dialogPro.getSucceeded()) {
            log.setText("Status : Creating Files . . .");
dialogPro.getPackName(), dialogPro.getClName());
controller.getClassName(0), controller.getCode(0));

        addTab(dialogPro.getClName(), dialogPro.getClName());
        projectName = dialogPro.getProName();
            Thread work = new Thread() {
                public void run() {
                    createNewPro(dialogPro.getProName(), dialogPro.getPackName(), dialogPro.getClName());
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            updateTab(0,controller.getCode(0));
                            setFileTree();
                        }
                    });
                }
            };
            work.start();

        }
    }

    private void createNewPro(String proName, String packName, String clName) {
        controller.createNewProject(proName, packName, clName);
        log.setText("Status : " + controller.getMessage());
    }


    private void updateTab(int index, String text){

        Component comp = textAreaPane.getComponentAt(index);
        if (comp instanceof JScrollPane) {
            JScrollPane pane = (JScrollPane) comp;
            Component comp2 = pane.getComponent(0);
            JViewport viewport = pane.getViewport();  
            if(viewport.getView() instanceof JEditorPane){
                JEditorPane edit = (JEditorPane) viewport.getView();
                edit.setText(text);
            }
        }
    }

    private void addTab(String name, String desc) {
        // TODO think about the text or direct from file
        JEditorPane edit = new JEditorPane();
        JScrollPane scrollPane = new JScrollPane(edit);
        edit.setContentType("text/java");
        ImageIcon icon = new ImageIcon(getClass().getResource(IMAGE_PATH + "new16.gif"));
        textAreaPane.addTab(name, icon, scrollPane, desc);
        textAreaPane.setTabComponentAt(textAreaPane.getComponentCount()-1,new ButtonTabComponent(textAreaPane,icon));
    }

    private void setFileTree(){
        DefaultTreeModel model;
        DefaultMutableTreeNode top = new DefaultMutableTreeNode("Projects");
        top.add(FileHandling.listFiles(new DefaultMutableTreeNode(projectName), Config.getPath()+projectName, ".java"));
        model = new DefaultTreeModel(top);
        fileTree = new JTree(model);
        fileTreeScroll.setViewportView(fileTree);
        horSplit.setLeftComponent(fileTreeScroll);
    }

    public void showNewFileDialog() {
        System.out.println("Action event of New File button.");
        NewJavaFile dialogFile = new NewJavaFile(frame, true);
        System.out.println(dialogFile.getSize());
        dialogFile.setVisible(true);
    }

    public void showOpenProDialog() {
        System.out.println("Action event of open button.");
        OpenProject dialogOpen = new OpenProject(frame, true);
        dialogOpen.setVisible(true);
        if (dialogOpen.getNewClicked()) {
            showNewProDialog();
        }
    }


    class UpdateListener implements DocumentListener {

        public void insertUpdate(DocumentEvent e) {
            textChanged = true;
        }

        public void removeUpdate(DocumentEvent e) {
            textChanged = true;
        }

        public void changedUpdate(DocumentEvent e) {
            textChanged = true;
        }
    }

    private class MyAction extends AbstractAction {

        String name;

        public MyAction(String name, Icon icon) {
            super(name, icon);
            this.name = name;
        }

        public MyAction(String name, Icon icon,
                Integer mnemonic, KeyStroke accelorator) {
            super(name, icon);
            putValue(Action.MNEMONIC_KEY, mnemonic);
            putValue(Action.ACCELERATOR_KEY, accelorator);
            this.name = name;
        }

        public MyAction(String name, Icon icon, String desc,
                Integer mnemonic, KeyStroke accelorator) {
            super(name, icon);
            putValue(Action.SHORT_DESCRIPTION, desc);
            putValue(Action.MNEMONIC_KEY, mnemonic);
            putValue(Action.ACCELERATOR_KEY, accelorator);
            this.name = name;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            switch (name) {
                case "New Project":
                    showNewProDialog();
                    break;
                case "New Java File":
                    showNewFileDialog();
                    break;
                case "Open":
                    showOpenProDialog();
                    break;
                case "Save":
                    System.out.println("Action event of save button.");
                    break;
                case "Exit":
                    System.out.println("Action event of exit button.");
                    System.exit(0);
                    break;
                case "Undo":
                    System.out.println("Action event of Undo button.");
                    break;
                case "Redo":
                    System.out.println("Action event of Redo button.");
                    break;
                case "Cut":
                    System.out.println("Action event of Cut button.");
                    break;
                case "Copy":
                    System.out.println("Action event of Copy button.");
                    break;
                case "Paste":
                    System.out.println("Action event of Paste button.");
                    break;
                case "Find":
                    System.out.println("Action event of Find button.");
                    break;
                case "Replace":
                    System.out.println("Action event of Replace button.");
                    break;
                case "Run":
                    System.out.println("Action event of Run button.");
                    compileCode();
                    break;

            }
        }
    }
}

1 个答案:

答案 0 :(得分:3)

private class MyAction extends AbstractAction

将引用MainScreen.this对象。这就是为什么你可以从MyAction类中调用它。当您将其移动到新文件时,您将无法再访问MainScreen.this。

当你将MyAction类拉出到一个新文件时,给它一个构造函数,它接受一个MainScreen对象(或者更好的是,一个MainScreen实现的接口)并将其保存在一个成员var中。例如,界面将具有方法showNewFileDialog();

然后,调用该成员var上的方法,例如mainScreen.showNewFileDialog()

通过此实现,您可以重用MyAction类

示例MyAction类:

public class MyAction extends AbstractAction {

    String name;

    MainScreen mainScreen;

    public MyAction(String name, Icon icon, MainScreen s) {
        super(name, icon);
        this.name = name;
        this.mainScreen = s;
    }

    public MyAction(String name, Icon icon,
            Integer mnemonic, KeyStroke accelorator,) {
        super(name, icon);
        putValue(Action.MNEMONIC_KEY, mnemonic);
        putValue(Action.ACCELERATOR_KEY, accelorator);
        this.name = name;
        this.mainScreen = s;
    }

    public void actionPerformed(ActionEvent e) {
        switch (name) {
            case "New Project":
                mainScreen.showNewProDialog();
                break;
            case "New Java File":
                mainScreen.showNewFileDialog();
                break;
            case "Open":
                showOpenProDialog();
                break;
            case "Save":
                System.out.println("Action event of save button.");
                break;
            case "Exit":
                System.out.println("Action event of exit button.");
                System.exit(0);
                break;
            case "Undo":
                System.out.println("Action event of Undo button.");
                break;
            case "Redo":
                System.out.println("Action event of Redo button.");
                break;
            case "Cut":
                System.out.println("Action event of Cut button.");
                break;
            case "Copy":
                System.out.println("Action event of Copy button.");
                break;
            case "Paste":
                System.out.println("Action event of Paste button.");
                break;
            case "Find":
                System.out.println("Action event of Find button.");