Reputation: 1
I'm making a very poor attempt at ActionListeners here.
I'm trying to use ActionListeners to run code from in another class (AddForm.java) once a JMenuItem (in MainMenu.java) is clicked.
First, here's the code: 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);
}
On the main frame I have drawn a series of shapes which will appear on the Frame at first. And there will be a JMenu above this with the JMenuItems Add, Remove and Search Cars in the menu.
Once these Add Remove and Search 'menu buttons' are clicked they will open the corresponding form which will allow the user to input data.
When I run my code with and without the action listeners, it runs as normal but the menus don't link at all. It's as if they have no meaning?
Upvotes: 0
Views: 109
Reputation: 285405
Some basic issues:
For a simple non-MVC example, you could have one class calling methods of the second. Assume a JPanel that holds a JList called View1 that has a public method, addItem(String item)
that adds items tot he JList's model:
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);
}
}
Consider a second JPanel class, View2, that holds a JTextArea and a JButton and an instance of View1. This second class could then call the addItem(...)
method of View1:
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();
}
}
}
You then could create the two classes, passing View1 into View2's constructor
View1 view1 = new View1();
View2 view2 = new View2(view1);
And then put one into a JFrame the other into a non-modal JDialog and display. For instance:
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();
}
}
}
Upvotes: 2