我正在编写一个需要大量摆动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;
}
}
}
}
最佳答案
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.");