2014-12-01 51 views
0

我在ActionListeners這裏做了一個很差的嘗試。ActionListeners JMenuItems - 跨類

我試圖使用ActionListeners從另一個類(AddForm.java)運行代碼,一旦JMenuItem(在MainMenu.java)被點擊。

首先,這裏的代碼:MainMenu.java

package carparksystem; 

import javax.swing.JFrame; 
import javax.swing.*; 
import java.awt.event.ActionListener; 
import java.awt.event.ActionEvent; 
import java.awt.*; 
import java.awt.event.*; 

public class MainMenu extends JFrame 
{ 
public MainMenu() 
{ 
    JMenuBar mainMenu = new JMenuBar(); 
    JMenu main = new JMenu("Menu"); 

    mainMenu.add(main); 

    JMenuItem addCar = new JMenuItem("Add Car"); 
    addCar.setActionCommand("Add"); 
    main.add(addCar); 
    //addCar.addActionListener(); 

    JMenuItem removeCar = new JMenuItem("Remove Car"); 
    removeCar.setActionCommand("Remove"); 
    main.add(removeCar); 

    JMenuItem searchCars = new JMenuItem("Search Cars"); 
    searchCars.setActionCommand("Search"); 
    main.add(searchCars); 

    setJMenuBar(mainMenu); 

    /* 
    //Add action listener for the Add Car button 
    addCar.addActionListener 
    (
     new ActionListener() 
      { 
       @Override 
       public void actionPerformed(ActionEvent e) 
       { 
        MainMenu.windowClosed(); 
       }  
      }   
    ); 
    */ 
} 
} 

AddForm.java:

package carparksystem; 

import javax.swing.ButtonGroup; 
import javax.swing.GroupLayout; 
import javax.swing.JButton; 
import javax.swing.JLabel; 
import javax.swing.JRadioButton; 
import javax.swing.JTextField; 
import javax.swing.WindowConstants; 
import javax.swing.JFrame; 

public class AddForm extends JFrame 
{ 
public AddForm() 
{   
    JLabel regNumLabel = new JLabel("Registration Number:"); 
    JLabel highValLabel = new JLabel("High Value?"); 
    JLabel largeLabel = new JLabel("Large Vehicle?"); 

    JRadioButton btnYesHighVal = new JRadioButton("Yes", false); 
    JRadioButton btnNoHighVal = new JRadioButton("No", true); 
    JRadioButton btnYesLarge = new JRadioButton("Yes", false); 
    JRadioButton btnNoLarge = new JRadioButton("No", true); 

    ButtonGroup highVal = new ButtonGroup();  //allows just one radio button from the group to be selected 
    highVal.add(btnYesHighVal); 
    highVal.add(btnNoHighVal); 

    ButtonGroup largeCar = new ButtonGroup();  //allows just one radio button from the group to be selected 
    largeCar.add(btnYesLarge); 
    largeCar.add(btnNoLarge); 

    JTextField regNumField = new JTextField(); 

    JButton addCar = new JButton(" Add "); 
    JButton addCancel = new JButton("Cancel"); 

    GroupLayout addLayout = new GroupLayout(getContentPane());  //chosen to display components in group layout 
    getContentPane().setLayout(addLayout); 
    addLayout.setAutoCreateGaps(true); 
    addLayout.setAutoCreateContainerGaps(true); 

    addLayout.setHorizontalGroup(addLayout.createSequentialGroup() 
     .addGroup(addLayout.createParallelGroup(GroupLayout.Alignment.LEADING) 
      .addComponent(regNumLabel) 
      .addComponent(highValLabel) 
      .addComponent(largeLabel)) 
     .addGroup(addLayout.createParallelGroup(GroupLayout.Alignment.LEADING) 
      .addComponent(regNumField) 
      .addGroup(addLayout.createSequentialGroup() 
       .addGroup(addLayout.createParallelGroup(GroupLayout.Alignment.LEADING) 
       .addComponent(btnYesHighVal) 
       .addComponent(btnYesLarge)) 
      .addGroup(addLayout.createParallelGroup(GroupLayout.Alignment.LEADING) 
       .addComponent(btnNoHighVal) 
       .addComponent(btnNoLarge)))) 
     .addGroup(addLayout.createParallelGroup(GroupLayout.Alignment.LEADING) 
      .addComponent(addCar) 
      .addComponent(addCancel)) 
    ); 

    addLayout.setVerticalGroup(addLayout.createSequentialGroup() 
     .addGroup(addLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) 
      .addComponent(regNumLabel) 
      .addComponent(regNumField) 
      .addComponent(addCar)) 
     .addGroup(addLayout.createParallelGroup(GroupLayout.Alignment.LEADING) 
      .addGroup(addLayout.createSequentialGroup() 
       .addGroup(addLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) 
        .addComponent(highValLabel) 
        .addComponent(btnYesHighVal) 
        .addComponent(btnNoHighVal)) 
       .addGroup(addLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) 
        .addComponent(largeLabel)  
        .addComponent(btnYesLarge) 
        .addComponent(btnNoLarge))) 
       .addComponent(addCancel)) 
     ); 

    setSize(375, 150); 
    setTitle("Add Car"); 
    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 
} 

在主框架我畫了一系列的形狀,這將首先出現在相框。在菜單中,JMenuItems Add,Remove和Search Cars將會有一個JMenu。

一旦這些添加刪除和搜索菜單按鈕被點擊,他們將打開相應的表格,這將允許用戶輸入數據。

當我使用和不使用動作偵聽器運行我的代碼時,它運行正常,但菜單根本不鏈接。就好像他們沒有意義?

+3

我強烈建議您將標題修改爲更有意義的內容。 – 2014-12-01 22:49:14

回答

2

一些基本問題:

  • 如果一個類是具有對另一效果,它需要的是其他類的引用,以便它可以在其所有的方法。
  • 因此,如果您的MainMenu類需要更改AddForm類的狀態,那麼MainMenu將需要一個AddForm字段,更重要的是,該字段必須引用當前活動的AddForm對象。
  • 更好的程序結構是使用M-V-C或模型 - 視圖 - 控制結構,其中兩個視圖通過共享模型連接,但對於簡單的程序來說,這可能有點高級。如果你想遵循最佳實踐,這將是一條路。 This example顯示了一個更簡單的視圖控制的想法,也可以工作。
  • GUI對於多個頂層窗口來說通常是個壞主意,對於Java而言,這意味着多個JFrame。最好有一個主窗口和其他視圖,如果需要使用CardLayout,可以在其中進行交換,或者可以在需要時顯示在對話框窗口中。請查看The Use of Multiple JFrames, Good/Bad Practice?

對於一個簡單的非MVC例如,你可以有第二個的一類調用方法。假設擁有一個JList稱爲視圖1有一個公共的方法,addItem(String item),增加了項目TOT他Jlist的模型一個JPanel:

public class View1 extends JPanel { 
    private static final String PROTOTYPE = String.format("%50s", " "); 
    private DefaultListModel<String> listModel = new DefaultListModel<>(); 
    private JList<String> list = new JList<>(listModel); 

    public View1() { 
     list.setPrototypeCellValue(PROTOTYPE); 
     list.setVisibleRowCount(8); 
     JScrollPane scrollPane = new JScrollPane(list); 
     scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 
     add(scrollPane); 
    } 

    public void addItem(String item) { 
     listModel.addElement(item); 
    } 
} 

看一下第二個JPanel類,視圖2,持有一個JTextArea和JButton,並實例廠景。那麼這第二類可以調用視圖1的addItem(...)方法:

public class View2 extends JPanel { 
    private View1 view1; 
    private JTextField textField = new JTextField(10); 

    public View2(View1 view1) { 
     Action addItemAction = new AddItemAction(); 
     this.view1 = view1; 
     add(textField); 
     add(new JButton(addItemAction)); 
     textField.setAction(addItemAction); 
    } 

    private class AddItemAction extends AbstractAction { 
     public AddItemAction() { 
     super("Add Item"); 
     putValue(MNEMONIC_KEY, KeyEvent.VK_A); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
     view1.addItem(textField.getText()); // *** calls view1's method here 
     textField.selectAll(); 
     } 
    } 
} 

然後,您可以創建兩個類,通過視圖1到視圖2的構造

View1 view1 = new View1(); 
    View2 view2 = new View2(view1); 

然後把一個到一個JFrame其他成非模態的JDialog和顯示。例如:

import java.awt.Dialog.ModalityType; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 

import javax.swing.*; 

public class SimpleGuis { 
    private static void createAndShowGui() { 
     View1 view1 = new View1(); 
     View2 view2 = new View2(view1); 

     JFrame frame = new JFrame("SimpleGuis"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(view1); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 

     JDialog dialog = new JDialog(frame, "View2", ModalityType.MODELESS); 
     dialog.add(view2); 
     dialog.pack(); 
     dialog.setLocationByPlatform(true); 
     dialog.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

class View1 extends JPanel { 
    private static final String PROTOTYPE = String.format("%50s", " "); 
    private DefaultListModel<String> listModel = new DefaultListModel<>(); 
    private JList<String> list = new JList<>(listModel); 

    public View1() { 
     list.setPrototypeCellValue(PROTOTYPE); 
     list.setVisibleRowCount(8); 
     JScrollPane scrollPane = new JScrollPane(list); 
     scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 
     add(scrollPane); 
    } 

    public void addItem(String item) { 
     listModel.addElement(item); 
    } 
} 

class View2 extends JPanel { 
    private View1 view1; 
    private JTextField textField = new JTextField(10); 

    public View2(View1 view1) { 
     Action addItemAction = new AddItemAction(); 
     this.view1 = view1; 
     add(textField); 
     add(new JButton(addItemAction)); 
     textField.setAction(addItemAction); 
    } 

    private class AddItemAction extends AbstractAction { 
     public AddItemAction() { 
     super("Add Item"); 
     putValue(MNEMONIC_KEY, KeyEvent.VK_A); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
     view1.addItem(textField.getText()); 
     textField.selectAll(); 
     } 
    } 
} 
+0

另外,'ActionListener'處理(Swing)'ActionEvent',但你可能需要做其他事情。不要將引用添加到類中,以便您可以方便地訪問其方法。相反,您可以使用其他機制(設計模式)在發生GUI事件時幫助在其他類上調用方法。 – hfontanez 2014-12-01 22:57:19

+1

@hfontanez:我同意,如果可能,最好去M-V-C。 – 2014-12-01 22:58:19

+0

我不確定你的意思與第一點。你是指什麼參考?這是我打算做到這一點的唯一方法,因爲我必須在明天完成它,現在改變它將是一場噩夢?!還有什麼是MVC?哈哈。 Java仍然很新。 – user3223921 2014-12-01 23:03:57