Java Swing GUI 创建 - 如何让动态创建的按钮正确更新
Java Swing GUI creation - How to get dynamically created buttons to update properly
我的大学项目是为我为早期项目制作的停车场应用程序创建一个工作 GUI。
停车场由员工停车场和游客停车场组成,GUI 会根据用户想要添加的数量动态地为每个停车场创建按钮。
我遇到的问题是在我最初创建我的停车场并接受 staff/visitor 个公园的用户输入后,这些公园按预期显示,除了单击每个公园以获取信息不起作用.
当我通过 'Add Car' 的选项时,无论我尝试将汽车添加到哪个插槽,它只会更新最终的游客公园...例如,如果有 5 个员工和游客公园,我添加一辆车到槽 S001,更改将反映在槽 V005。
PS。我对编程很陌生,如果格式和逻辑不正确,我深表歉意。此外,我们必须使用名为 BlueJ 的 IDE,对于此项目,我们不允许使用任何包含 GUI 创建器的 IDE。
如有任何提示,我们将不胜感激。
谢谢,迈克尔
该软件包包含 4 个 类:GUI、CarPark、ParkingSlot 和 Car。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.regex.*;
public class GUI extends JFrame
{
private JPanel panel;
private JButton but1;
private JButton but2;
private JButton but3;
private JButton but4;
private JButton but5;
private JButton but6;
private JButton button;
private static CarPark cp1 = new CarPark();
private static ParkingSlot ps = new ParkingSlot("", true, null);
public static final int YES_NO_OPTION = 0;
public static void main(String[] args)
{
JFrame myApp = new GUI();
myApp.setVisible(true);
}
public GUI()
{
//set size
super("Car Park Application");
createCarPark();
addButtons();
addListeners();
}
public void createCarPark()
{
JPanel staffFrame = new JPanel();
JPanel visitorFrame = new JPanel();
JPanel middle = new JPanel(new FlowLayout(FlowLayout.CENTER,100,10)); //panel to have staff/visitor parks
middle.add(staffFrame);
middle.add(visitorFrame);
add(middle, BorderLayout.CENTER);
// add a scrollpane
JScrollPane scrollPane = new JScrollPane(middle);
setPreferredSize(new Dimension(600, 400));
add(scrollPane, BorderLayout.CENTER);
int i = 0, j = 0;
String staffSlotNumber = "", visitorSlotNumber = "";
int staffSlots = Integer.parseInt(JOptionPane.showInputDialog(this,
"How many staff parks do you need?", "Create Staff Parks", 2));
int visitorSlots = Integer.parseInt(JOptionPane.showInputDialog(this,
"How many visitor parks do you need?", "Create Visitor Parks", 2));
JOptionPane.showMessageDialog(this,"Staff parks created: " + staffSlots +
"\nVisitor parks created: " + visitorSlots,
"Car Park Created!",JOptionPane.WARNING_MESSAGE );
//Create the actual car park
while (i < staffSlots)
{
if (i <9)
{
staffSlotNumber = "S00";
}
else if (i <99)
{
staffSlotNumber = "S0";
}
else if (i <999)
{
staffSlotNumber = "S";
}
else
{
JOptionPane.showMessageDialog(this,"No parks created. Exit and try again.",
"Massive error. Exit and try again.",JOptionPane.WARNING_MESSAGE );
}
ParkingSlot ps = new ParkingSlot(staffSlotNumber+(i+1), true, null);
cp1.addParkingSlot(ps);
button = new JButton(ps.toString());
staffFrame.add(button);
i++;
}
while (j < visitorSlots)
{
//
if (j <9)
{
visitorSlotNumber = "V00";
}
else if (j <99)
{
visitorSlotNumber = "V0";
}
else if (j <999)
{
visitorSlotNumber = "V";
}
else
{
JOptionPane.showMessageDialog(this,"No parks created. Exit and try again.",
"Massive error. Exit and try again.",JOptionPane.WARNING_MESSAGE );
}
//
ParkingSlot ps = new ParkingSlot(visitorSlotNumber+(j+1), false, null);
cp1.addParkingSlot(ps);
button = new JButton(ps.toString());
visitorFrame.add(button);
j++;
}
staffFrame.setLayout(new GridLayout(staffSlots,1));
visitorFrame.setLayout(new GridLayout(visitorSlots,1));
setSize(1200,600);
setVisible(true);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void addButtons()
{
but1 = new JButton("Add Car");
but2 = new JButton("Remove Car");
but3 = new JButton("Find Car");
but4 = new JButton("Add Car Park");
but5 = new JButton("Remove Car Park");
but6 = new JButton("Exit");
JPanel buttonPanel = new JPanel( );
buttonPanel.setLayout(new GridLayout(2,3));
buttonPanel.add(but1);
buttonPanel.add(but2);
buttonPanel.add(but3);
buttonPanel.add(but4);
buttonPanel.add(but5);
buttonPanel.add(but6);
add(buttonPanel, BorderLayout.SOUTH);
}
public void addListeners()
{
//add listeners
but1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
addCar();
}
});
but2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
removeCar();
}
});
but3.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
findCar();
}
});
but4.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
addPark();
}
});
but5.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
removePark();
}
});
but6.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
exitApp();
}
});
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
button.setText(ps.toString());
}
});
pack();
}
public void addCar()
{
boolean staff;
String staffStr;
String carRego = "";
do
{
carRego = JOptionPane.showInputDialog(this,
"Please input a registration to add.\nUse format A12345", "Add Car - Registration", 3);
} while (!Pattern.matches("[A-Z]{1}[0-9]{5}", carRego));
String driverName = JOptionPane.showInputDialog(this,
"What is the driver's name?", "Add Car - Driver's Name", 3);
//send carRego to the CarPark class
String slotId = "";
do
{
slotId = JOptionPane.showInputDialog(this,
"Please input a slot ID.\nUse format S001", "Add Car - Slot ID", 3);
} while (!slotId.matches("[SV][0-9][0-9][0-9]"));
//if (slotId.charAt(0) == 'S')
int choice = JOptionPane.showConfirmDialog(this,
"Is this person a staff member?", "Staff Member?", JOptionPane.YES_NO_OPTION);
if (choice == JOptionPane.YES_OPTION)
{
staff = true;
staffStr = "They are a staff member.";
} else
{
staff = false;
staffStr = "They are a visitor.";
}
JOptionPane.showMessageDialog(this,"You have entered the registration: " + carRego +
"\nYou have entered the name: " + driverName +
"\nYou have entered the slot ID: " + slotId +
"\n" + staffStr,
"Registration and Slot ID Confirmation",JOptionPane.INFORMATION_MESSAGE );
Car car = new Car(carRego, driverName, staff);
ParkingSlot ps;
ps = cp1.findParkingSlot(slotId);
//staff-visitor check
if (ps == null)
{
//System.out.println("Please pick an existing car space.");
JOptionPane.showMessageDialog(
this,
"Please pick an existing car space.",
"Park doesn't exist.",
JOptionPane.PLAIN_MESSAGE);
}
else if (ps.hasCar())
{
//System.out.println("There is already a car in that place.");
JOptionPane.showMessageDialog(
this,
"There is already a car in that place.",
"Park doesn't exist.",
JOptionPane.PLAIN_MESSAGE);
}
else if (ps.getStaffPark() == true && staff == false)
{
//System.out.println("You cannot put a visitor in a staff park.");
JOptionPane.showMessageDialog(
this,
"You cannot put a visitor in a staff park.",
"Park doesn't exist.",
JOptionPane.PLAIN_MESSAGE);
}
else if (ps.getStaffPark() == false && staff == true)
{
//System.out.println("You cannot put staff in a visitor park.");
JOptionPane.showMessageDialog(
this,
"You cannot put staff in a visitor park.",
"Park doesn't exist.",
JOptionPane.PLAIN_MESSAGE);
}
else
{
//successful details are stored and output.
ps.setSlotNumber(slotId);
ps.setStaffPark(staff);
ps.parkCar(car);
button.setText(ps.toString());
revalidate();
repaint();
JOptionPane.showMessageDialog(
this,
"Success!\nYou added: " + carRego + " to park " + slotId + "." ,
"Parking Spot Addition",
JOptionPane.PLAIN_MESSAGE);
}
}
public void removeCar()
{
String carRego = "";
do
{
carRego = JOptionPane.showInputDialog(this,
"Which registration? Use format A12345", "Remove Car", 3);
} while (!carRego.matches("[A-Z][0-9]{5}"));
ParkingSlot ps = cp1.findCar(carRego);
if (ps != null)
{
ps.removeCar();
JOptionPane.showMessageDialog(this,"You have REMOVED the registration: " + carRego,
"Registration Removal Confirmation",JOptionPane.WARNING_MESSAGE );
}
else
{
JOptionPane.showMessageDialog(this,"Car registration " + carRego + " does not exist.",
"Registration Removal Failure",JOptionPane.WARNING_MESSAGE );
}
}
public void findCar()
{
//declare variables
String carRego = "";
String slotNumber;
ParkingSlot ps;
//prompt user with registration format check
do
{
carRego = JOptionPane.showInputDialog(this,
"Please enter car registration (eg A12345):", "Find Car", 2);
} while (!carRego.matches("[A-Z][0-9]{5}"));
//find car rego in carpark array list
ps = cp1.findCar(carRego);
//check for incorrect format/inputs
if(ps == null)
{
JOptionPane.showMessageDialog(this,"Car registration " + carRego + " does not exist.",
"Find Car - Unsuccessful",JOptionPane.WARNING_MESSAGE );
}
else
{
JOptionPane.showMessageDialog(this, "Success, the car has been found!\nOwner: "+ ps.getCar().getName()
+ "\nRegistration: " + ps.getCar().getRego()
+ "\nCar park location: [" + ps.getSlotNumber() + "]",
"Find Car - Successful",JOptionPane.WARNING_MESSAGE );
}
}
public void addPark()
{
String slotNumber = "";
do
{
slotNumber = JOptionPane.showInputDialog(this,
"Please input a new car park ID to add to the car park eg S001", "Add a new slot ID", 2);
} while (!slotNumber.matches("[SV]\d\d\d"));
JOptionPane.showMessageDialog(this,"You have ADDED to the car park: " + slotNumber,
"Add a new parking spot",JOptionPane.INFORMATION_MESSAGE );
ParkingSlot ps;
Car car = null;
boolean staff;
if (slotNumber.toUpperCase().charAt(0) == 'S')
{
staff = true;
}
else
{
staff = false;
}
ps = cp1.findParkingSlot(slotNumber);
if (ps != null)
{
JOptionPane.showMessageDialog(this,"This parking slot number already exists. Choose another."
+ slotNumber,"Add a new parking spot",JOptionPane.INFORMATION_MESSAGE );
return;
}
else
{
cp1.addParkingSlot(new ParkingSlot(slotNumber,staff, car));
JOptionPane.showMessageDialog(this,"Sucess! You have added slot: "
+ slotNumber,"Add a new parking spot",JOptionPane.INFORMATION_MESSAGE );
}
//System.out.println("New slot " + slotNumber + " has been added to the car park.");
System.out.println(cp1.toString());
}
public void removePark()
{
String slotNumber;
ParkingSlot ps;
do
{
slotNumber = JOptionPane.showInputDialog(this,
"Please input an existing parking spot to REMOVE from the car park", "Remove Park", 2);
//System.out.println("Which park would you like to remove? Enter slot number");
//slotNumber = input.nextLine();
} while (!slotNumber.matches("[SV]\d\d\d"));
ps = cp1.findParkingSlot(slotNumber);
if (ps != null)
{
if (ps.hasCar())
{
JOptionPane.showMessageDialog(this,"The parking slot is occupied, you cannot remove it.",
"Remove Park - Unsuccessful",JOptionPane.WARNING_MESSAGE );
//System.out.println("The parking slot is occupied, you cannot remove it.");
}
else
{
cp1.removeParkingSlot(ps);
JOptionPane.showMessageDialog(this,"Parking slot :" + slotNumber
+ " was vacant, and has been removed.",
"Remove park - Successful",JOptionPane.WARNING_MESSAGE );
//System.out.println("Parking slot " + slotNumber + " was vacant, and has been removed.");
}
}
else
{
JOptionPane.showMessageDialog(this,"The parking slot doesn't exist",
"Remove Park - Unsuccessful",JOptionPane.WARNING_MESSAGE );
//System.out.println("Unable to perform action. That parking slot does not exist");
}
if (cp1.numberOfparks() == 0)
{
JOptionPane.showMessageDialog(this,"All parks removed",
"Remove Park - Successful",JOptionPane.WARNING_MESSAGE );System.out.println("All parks have been removed.");
}
}
public void exitApp()
{
System.exit(0);
}
}
import java.util.ArrayList;
public class CarPark {
public ArrayList<ParkingSlot> parks;
public CarPark()
{
parks = new ArrayList<ParkingSlot>();
}
public ArrayList<ParkingSlot> getParks()
{
return parks;
}
public String toString()
{
String parkingString = "";
for (ParkingSlot parkingSlot : parks)
{
parkingString += parkingSlot.toString() + "\n";
}
if (parkingString.equals(""))
{
parkingString = "No parking spots exist.";
}
return parkingString;
}
public void addParkingSlot(ParkingSlot parkingSlot)
{
parks.add(parkingSlot);
}
public void removeParkingSlot(ParkingSlot parkingSlot)
{
parks.remove(parkingSlot);
}
public int numberOfparks()
{
return parks.size();
}
public ParkingSlot findParkingSlot(String slotNumber)
{
for (ParkingSlot parkingSlot : parks)
{
if (parkingSlot.getSlotNumber().equals(slotNumber))
{
return parkingSlot;
}
}
return null;
}
public ParkingSlot findCar(String findRego)
{
ParkingSlot ps = null;
for(int i = 0; i < parks.size(); i++)
{
ps = parks.get(i);
// check to see if there's a car object in a park.
Car car = ps.getCar();
if(car != null && findRego.equals(car.getRego()))
return ps;
}
return null;
}
}
public class ParkingSlot
{
//variables required for parking slot.
private String slotNumber;
private boolean staffPark;
private Car car;
public ParkingSlot(String slotNumber, boolean staffPark, Car car)
{
this.slotNumber = slotNumber;
this.staffPark = staffPark;
this.car = null;
}
public String getSlotNumber()
{
return slotNumber;
}
public void setSlotNumber(String newSlotNumber)
{
slotNumber = newSlotNumber;
}
public boolean getStaffPark()
{
return staffPark;
}
public void setStaffPark(boolean newStaffPark)
{
staffPark = newStaffPark;
}
public Car getCar()
{
return car;
}
public void parkCar(Car car)
{
this.car = car;
}
public void removeCar()
{
car = null;
}
public boolean hasCar()
{
return this.car != null;
}
public String toString()
{
//String staffOrVisitor = "] [ Staff Park ] ";
String staffOrVisitor = "Park: ";
String taken = "is taken";
if (staffPark == false)
{
//staffOrVisitor = "] [Visitor Park] ";
staffOrVisitor = "Park: ";
}
if (car == null)
{
taken = " [vacant]";
}
else
{
taken = " contains vehicle, registration [" + car.getRego() + "]";
}
return staffOrVisitor + slotNumber + taken;
// return "Park [" + slotNumber + staffOrVisitor + taken;
}
}
public class Car {
// instance variables
private String rego;
private String name;
private boolean staff;
public Car(String rego, String name, boolean staff)
{
this.rego = rego;
this.name = name;
this.staff = staff;
}
public String toString()
{
return "Registration " + rego + " - Name: " + name + " - Staff member: " + staff;
}
public String getRego(){
return rego;
}
public void setRego(String newRego){
rego = newRego;
}
public String getName(){
return name;
}
public void setName(String newName){
name = newName;
}
public boolean getStaff(){
return staff;
}
public void setStaff(boolean newStaff){
staff = newStaff;
}
}
同样,问题在于创建模型并以某种方式将其绑定到您的视图(GUI)。最好是在这两个 类 或 类 组之间创建并保持良好的分离,但为了在这种情况下使事情更简单,我们可以在 GUI 中组合它们。为了向您展示我的意思,考虑一下您的代码的这种简化,它使用非常简单的 Car 和 ParkingSlot 类:
public class Car {
private String name;
public Car(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Car: " + name;
}
}
public class ParkingSlot {
private Car car;
private String name;
public ParkingSlot(String name) {
this.name = name;
}
public void setCar(Car car) {
this.car = car;
}
public Car getCar() {
return car;
}
public void clear() {
car = null;
}
public String getName() {
return name;
}
@Override
public String toString() {
String value = "Slot: " + name + "; ";
if (car == null) {
value += "empty";
} else {
value += car.toString();
}
return value;
}
}
我想要一个将 String 绑定到 ParkingSlot 的模型,为此,最好使用 Map<String, ParkingSlot>
。这是一个包含 ParkingSlot 对象并使它们可以通过插槽的“名称”String 访问的集合。我经常将它初始化为 new HashMap<String, ParkingSlot>()
,但我也想维护 Map 中的插入顺序,这样如果我遍历它,它就不会以某种随机顺序(因为 HashMap 往往是),所以,我将使用 LinkedHashMap<String, ParkingSlot>
对其进行初始化,因为这就像 HashMap 但保留了插入顺序:
private Map<String, ParkingSlot> slotMap = new LinkedHashMap<>();
因此,如果稍后我想遍历集合,显示 ParkingSlot 对象的状态,我可以简单地使用 for 循环:
for (Entry<String, ParkingSlot> entry : slotMap.entrySet()) {
System.out.printf("%s%n", entry.getValue());
}
因此,现在在创建 JButton 网格时,使用定义插槽的字符串将其与 ParkingSlot 对象的集合相关联。这可以是 Map
的 key
,也可以通过使用它来设置按钮的 actionCommand 与 JButton 相关联,每个按钮都带有一个字符串:
JPanel gridPanel = new JPanel(new GridLayout(0, 1));
for (int i = 0; i < slotCount; i++) {
String slotName = String.format("V%03d", i);
ParkingSlot slot = new ParkingSlot(slotName);
slotMap.put(slotName, slot);
JButton button = new JButton(slotName + ": Empty");
button.setActionCommand(slotName);
button.addActionListener(e -> parkingSlotButtonAction(e));
gridPanel.add(button);
}
当任意一个按钮被按下时,调用parkingSlotButtonAction(ActionEvent e)
方法,调用参数e.getSource()
获取源JButton,调用e.getSource()
获取按钮的actionCommand =24=] 在同一个参数上。它可以使用 slotMap
:
获取关联的 ParkingSlot 对象
private void parkingSlotButtonAction(ActionEvent e) {
String slotName = e.getActionCommand();
JButton source = (JButton) e.getSource();
ParkingSlot slot = slotMap.get(slotName);
// .....
}
一个完整的简单示例如下所示:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.*;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.*;
import javax.swing.event.ChangeListener;
public class SimpleLotMain {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
LotGui gui = new LotGui(20);
JFrame frame = new JFrame("Lot");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(gui);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
@SuppressWarnings("serial")
class LotGui extends JPanel {
private Map<String, ParkingSlot> slotMap = new LinkedHashMap<>();
public LotGui(int slotCount) {
JPanel gridPanel = new JPanel(new GridLayout(0, 1));
for (int i = 0; i < slotCount; i++) {
String slotName = String.format("V%03d", i);
ParkingSlot slot = new ParkingSlot(slotName);
slotMap.put(slotName, slot);
JButton button = new JButton(slotName + ": Empty");
button.setActionCommand(slotName);
button.addActionListener(e -> parkingSlotButtonAction(e));
gridPanel.add(button);
}
JScrollPane scrollPane = new JScrollPane(gridPanel);
scrollPane.getViewport().setPreferredSize(new Dimension(400, 400));
JButton displaySlotsBtn = new JButton("Display Parking Spots");
displaySlotsBtn.addActionListener(e -> displaySlots());
JPanel bottomPanel = new JPanel();
bottomPanel.add(displaySlotsBtn);
setLayout(new BorderLayout());
add(scrollPane);
add(bottomPanel, BorderLayout.PAGE_END);
}
private void parkingSlotButtonAction(ActionEvent e) {
String slotName = e.getActionCommand();
JButton source = (JButton) e.getSource();
ParkingSlot slot = slotMap.get(slotName);
// JOptionPane to query whether to add/remove car
String carName = JOptionPane.showInputDialog("Enter Name of Car to Add");
// if the user cancels the dialog or enters only white-space text: exit
if (carName == null || carName.trim().isEmpty()) {
return;
}
// else, use the name
Car car = new Car(carName);
slot.setCar(car);
String text = slotName + ": " + carName;
source.setText(text);
}
private void displaySlots() {
for (Entry<String, ParkingSlot> entry : slotMap.entrySet()) {
System.out.printf("%s%n", entry.getValue());
}
}
}
//class SLot {
// List<ParkingSlot> slots = new ArrayList<>();
//
// public SLot(int carCount) {
// for (int i = 0; i < carCount; i++) {
// String name = String.format("S%03d", i);
// slots.add(new ParkingSlot(name));
// }
// }
//
// @Override
// public String toString() {
// return "SLot [slots=" + slots + "]";
// }
//
// public void addChangeListener(ChangeListener l) {
//
// }
//}
class Car {
private String name;
public Car(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Car: " + name;
}
}
class ParkingSlot {
private Car car;
private String name;
public ParkingSlot(String name) {
this.name = name;
}
public void setCar(Car car) {
this.car = car;
}
public Car getCar() {
return car;
}
public void clear() {
car = null;
}
public String getName() {
return name;
}
@Override
public String toString() {
String value = "Slot: " + name + "; ";
if (car == null) {
value += "empty";
} else {
value += car.toString();
}
return value;
}
}
我的大学项目是为我为早期项目制作的停车场应用程序创建一个工作 GUI。
停车场由员工停车场和游客停车场组成,GUI 会根据用户想要添加的数量动态地为每个停车场创建按钮。
我遇到的问题是在我最初创建我的停车场并接受 staff/visitor 个公园的用户输入后,这些公园按预期显示,除了单击每个公园以获取信息不起作用.
当我通过 'Add Car' 的选项时,无论我尝试将汽车添加到哪个插槽,它只会更新最终的游客公园...例如,如果有 5 个员工和游客公园,我添加一辆车到槽 S001,更改将反映在槽 V005。
PS。我对编程很陌生,如果格式和逻辑不正确,我深表歉意。此外,我们必须使用名为 BlueJ 的 IDE,对于此项目,我们不允许使用任何包含 GUI 创建器的 IDE。
如有任何提示,我们将不胜感激。
谢谢,迈克尔
该软件包包含 4 个 类:GUI、CarPark、ParkingSlot 和 Car。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.regex.*;
public class GUI extends JFrame
{
private JPanel panel;
private JButton but1;
private JButton but2;
private JButton but3;
private JButton but4;
private JButton but5;
private JButton but6;
private JButton button;
private static CarPark cp1 = new CarPark();
private static ParkingSlot ps = new ParkingSlot("", true, null);
public static final int YES_NO_OPTION = 0;
public static void main(String[] args)
{
JFrame myApp = new GUI();
myApp.setVisible(true);
}
public GUI()
{
//set size
super("Car Park Application");
createCarPark();
addButtons();
addListeners();
}
public void createCarPark()
{
JPanel staffFrame = new JPanel();
JPanel visitorFrame = new JPanel();
JPanel middle = new JPanel(new FlowLayout(FlowLayout.CENTER,100,10)); //panel to have staff/visitor parks
middle.add(staffFrame);
middle.add(visitorFrame);
add(middle, BorderLayout.CENTER);
// add a scrollpane
JScrollPane scrollPane = new JScrollPane(middle);
setPreferredSize(new Dimension(600, 400));
add(scrollPane, BorderLayout.CENTER);
int i = 0, j = 0;
String staffSlotNumber = "", visitorSlotNumber = "";
int staffSlots = Integer.parseInt(JOptionPane.showInputDialog(this,
"How many staff parks do you need?", "Create Staff Parks", 2));
int visitorSlots = Integer.parseInt(JOptionPane.showInputDialog(this,
"How many visitor parks do you need?", "Create Visitor Parks", 2));
JOptionPane.showMessageDialog(this,"Staff parks created: " + staffSlots +
"\nVisitor parks created: " + visitorSlots,
"Car Park Created!",JOptionPane.WARNING_MESSAGE );
//Create the actual car park
while (i < staffSlots)
{
if (i <9)
{
staffSlotNumber = "S00";
}
else if (i <99)
{
staffSlotNumber = "S0";
}
else if (i <999)
{
staffSlotNumber = "S";
}
else
{
JOptionPane.showMessageDialog(this,"No parks created. Exit and try again.",
"Massive error. Exit and try again.",JOptionPane.WARNING_MESSAGE );
}
ParkingSlot ps = new ParkingSlot(staffSlotNumber+(i+1), true, null);
cp1.addParkingSlot(ps);
button = new JButton(ps.toString());
staffFrame.add(button);
i++;
}
while (j < visitorSlots)
{
//
if (j <9)
{
visitorSlotNumber = "V00";
}
else if (j <99)
{
visitorSlotNumber = "V0";
}
else if (j <999)
{
visitorSlotNumber = "V";
}
else
{
JOptionPane.showMessageDialog(this,"No parks created. Exit and try again.",
"Massive error. Exit and try again.",JOptionPane.WARNING_MESSAGE );
}
//
ParkingSlot ps = new ParkingSlot(visitorSlotNumber+(j+1), false, null);
cp1.addParkingSlot(ps);
button = new JButton(ps.toString());
visitorFrame.add(button);
j++;
}
staffFrame.setLayout(new GridLayout(staffSlots,1));
visitorFrame.setLayout(new GridLayout(visitorSlots,1));
setSize(1200,600);
setVisible(true);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void addButtons()
{
but1 = new JButton("Add Car");
but2 = new JButton("Remove Car");
but3 = new JButton("Find Car");
but4 = new JButton("Add Car Park");
but5 = new JButton("Remove Car Park");
but6 = new JButton("Exit");
JPanel buttonPanel = new JPanel( );
buttonPanel.setLayout(new GridLayout(2,3));
buttonPanel.add(but1);
buttonPanel.add(but2);
buttonPanel.add(but3);
buttonPanel.add(but4);
buttonPanel.add(but5);
buttonPanel.add(but6);
add(buttonPanel, BorderLayout.SOUTH);
}
public void addListeners()
{
//add listeners
but1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
addCar();
}
});
but2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
removeCar();
}
});
but3.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
findCar();
}
});
but4.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
addPark();
}
});
but5.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
removePark();
}
});
but6.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
exitApp();
}
});
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
button.setText(ps.toString());
}
});
pack();
}
public void addCar()
{
boolean staff;
String staffStr;
String carRego = "";
do
{
carRego = JOptionPane.showInputDialog(this,
"Please input a registration to add.\nUse format A12345", "Add Car - Registration", 3);
} while (!Pattern.matches("[A-Z]{1}[0-9]{5}", carRego));
String driverName = JOptionPane.showInputDialog(this,
"What is the driver's name?", "Add Car - Driver's Name", 3);
//send carRego to the CarPark class
String slotId = "";
do
{
slotId = JOptionPane.showInputDialog(this,
"Please input a slot ID.\nUse format S001", "Add Car - Slot ID", 3);
} while (!slotId.matches("[SV][0-9][0-9][0-9]"));
//if (slotId.charAt(0) == 'S')
int choice = JOptionPane.showConfirmDialog(this,
"Is this person a staff member?", "Staff Member?", JOptionPane.YES_NO_OPTION);
if (choice == JOptionPane.YES_OPTION)
{
staff = true;
staffStr = "They are a staff member.";
} else
{
staff = false;
staffStr = "They are a visitor.";
}
JOptionPane.showMessageDialog(this,"You have entered the registration: " + carRego +
"\nYou have entered the name: " + driverName +
"\nYou have entered the slot ID: " + slotId +
"\n" + staffStr,
"Registration and Slot ID Confirmation",JOptionPane.INFORMATION_MESSAGE );
Car car = new Car(carRego, driverName, staff);
ParkingSlot ps;
ps = cp1.findParkingSlot(slotId);
//staff-visitor check
if (ps == null)
{
//System.out.println("Please pick an existing car space.");
JOptionPane.showMessageDialog(
this,
"Please pick an existing car space.",
"Park doesn't exist.",
JOptionPane.PLAIN_MESSAGE);
}
else if (ps.hasCar())
{
//System.out.println("There is already a car in that place.");
JOptionPane.showMessageDialog(
this,
"There is already a car in that place.",
"Park doesn't exist.",
JOptionPane.PLAIN_MESSAGE);
}
else if (ps.getStaffPark() == true && staff == false)
{
//System.out.println("You cannot put a visitor in a staff park.");
JOptionPane.showMessageDialog(
this,
"You cannot put a visitor in a staff park.",
"Park doesn't exist.",
JOptionPane.PLAIN_MESSAGE);
}
else if (ps.getStaffPark() == false && staff == true)
{
//System.out.println("You cannot put staff in a visitor park.");
JOptionPane.showMessageDialog(
this,
"You cannot put staff in a visitor park.",
"Park doesn't exist.",
JOptionPane.PLAIN_MESSAGE);
}
else
{
//successful details are stored and output.
ps.setSlotNumber(slotId);
ps.setStaffPark(staff);
ps.parkCar(car);
button.setText(ps.toString());
revalidate();
repaint();
JOptionPane.showMessageDialog(
this,
"Success!\nYou added: " + carRego + " to park " + slotId + "." ,
"Parking Spot Addition",
JOptionPane.PLAIN_MESSAGE);
}
}
public void removeCar()
{
String carRego = "";
do
{
carRego = JOptionPane.showInputDialog(this,
"Which registration? Use format A12345", "Remove Car", 3);
} while (!carRego.matches("[A-Z][0-9]{5}"));
ParkingSlot ps = cp1.findCar(carRego);
if (ps != null)
{
ps.removeCar();
JOptionPane.showMessageDialog(this,"You have REMOVED the registration: " + carRego,
"Registration Removal Confirmation",JOptionPane.WARNING_MESSAGE );
}
else
{
JOptionPane.showMessageDialog(this,"Car registration " + carRego + " does not exist.",
"Registration Removal Failure",JOptionPane.WARNING_MESSAGE );
}
}
public void findCar()
{
//declare variables
String carRego = "";
String slotNumber;
ParkingSlot ps;
//prompt user with registration format check
do
{
carRego = JOptionPane.showInputDialog(this,
"Please enter car registration (eg A12345):", "Find Car", 2);
} while (!carRego.matches("[A-Z][0-9]{5}"));
//find car rego in carpark array list
ps = cp1.findCar(carRego);
//check for incorrect format/inputs
if(ps == null)
{
JOptionPane.showMessageDialog(this,"Car registration " + carRego + " does not exist.",
"Find Car - Unsuccessful",JOptionPane.WARNING_MESSAGE );
}
else
{
JOptionPane.showMessageDialog(this, "Success, the car has been found!\nOwner: "+ ps.getCar().getName()
+ "\nRegistration: " + ps.getCar().getRego()
+ "\nCar park location: [" + ps.getSlotNumber() + "]",
"Find Car - Successful",JOptionPane.WARNING_MESSAGE );
}
}
public void addPark()
{
String slotNumber = "";
do
{
slotNumber = JOptionPane.showInputDialog(this,
"Please input a new car park ID to add to the car park eg S001", "Add a new slot ID", 2);
} while (!slotNumber.matches("[SV]\d\d\d"));
JOptionPane.showMessageDialog(this,"You have ADDED to the car park: " + slotNumber,
"Add a new parking spot",JOptionPane.INFORMATION_MESSAGE );
ParkingSlot ps;
Car car = null;
boolean staff;
if (slotNumber.toUpperCase().charAt(0) == 'S')
{
staff = true;
}
else
{
staff = false;
}
ps = cp1.findParkingSlot(slotNumber);
if (ps != null)
{
JOptionPane.showMessageDialog(this,"This parking slot number already exists. Choose another."
+ slotNumber,"Add a new parking spot",JOptionPane.INFORMATION_MESSAGE );
return;
}
else
{
cp1.addParkingSlot(new ParkingSlot(slotNumber,staff, car));
JOptionPane.showMessageDialog(this,"Sucess! You have added slot: "
+ slotNumber,"Add a new parking spot",JOptionPane.INFORMATION_MESSAGE );
}
//System.out.println("New slot " + slotNumber + " has been added to the car park.");
System.out.println(cp1.toString());
}
public void removePark()
{
String slotNumber;
ParkingSlot ps;
do
{
slotNumber = JOptionPane.showInputDialog(this,
"Please input an existing parking spot to REMOVE from the car park", "Remove Park", 2);
//System.out.println("Which park would you like to remove? Enter slot number");
//slotNumber = input.nextLine();
} while (!slotNumber.matches("[SV]\d\d\d"));
ps = cp1.findParkingSlot(slotNumber);
if (ps != null)
{
if (ps.hasCar())
{
JOptionPane.showMessageDialog(this,"The parking slot is occupied, you cannot remove it.",
"Remove Park - Unsuccessful",JOptionPane.WARNING_MESSAGE );
//System.out.println("The parking slot is occupied, you cannot remove it.");
}
else
{
cp1.removeParkingSlot(ps);
JOptionPane.showMessageDialog(this,"Parking slot :" + slotNumber
+ " was vacant, and has been removed.",
"Remove park - Successful",JOptionPane.WARNING_MESSAGE );
//System.out.println("Parking slot " + slotNumber + " was vacant, and has been removed.");
}
}
else
{
JOptionPane.showMessageDialog(this,"The parking slot doesn't exist",
"Remove Park - Unsuccessful",JOptionPane.WARNING_MESSAGE );
//System.out.println("Unable to perform action. That parking slot does not exist");
}
if (cp1.numberOfparks() == 0)
{
JOptionPane.showMessageDialog(this,"All parks removed",
"Remove Park - Successful",JOptionPane.WARNING_MESSAGE );System.out.println("All parks have been removed.");
}
}
public void exitApp()
{
System.exit(0);
}
}
import java.util.ArrayList;
public class CarPark {
public ArrayList<ParkingSlot> parks;
public CarPark()
{
parks = new ArrayList<ParkingSlot>();
}
public ArrayList<ParkingSlot> getParks()
{
return parks;
}
public String toString()
{
String parkingString = "";
for (ParkingSlot parkingSlot : parks)
{
parkingString += parkingSlot.toString() + "\n";
}
if (parkingString.equals(""))
{
parkingString = "No parking spots exist.";
}
return parkingString;
}
public void addParkingSlot(ParkingSlot parkingSlot)
{
parks.add(parkingSlot);
}
public void removeParkingSlot(ParkingSlot parkingSlot)
{
parks.remove(parkingSlot);
}
public int numberOfparks()
{
return parks.size();
}
public ParkingSlot findParkingSlot(String slotNumber)
{
for (ParkingSlot parkingSlot : parks)
{
if (parkingSlot.getSlotNumber().equals(slotNumber))
{
return parkingSlot;
}
}
return null;
}
public ParkingSlot findCar(String findRego)
{
ParkingSlot ps = null;
for(int i = 0; i < parks.size(); i++)
{
ps = parks.get(i);
// check to see if there's a car object in a park.
Car car = ps.getCar();
if(car != null && findRego.equals(car.getRego()))
return ps;
}
return null;
}
}
public class ParkingSlot
{
//variables required for parking slot.
private String slotNumber;
private boolean staffPark;
private Car car;
public ParkingSlot(String slotNumber, boolean staffPark, Car car)
{
this.slotNumber = slotNumber;
this.staffPark = staffPark;
this.car = null;
}
public String getSlotNumber()
{
return slotNumber;
}
public void setSlotNumber(String newSlotNumber)
{
slotNumber = newSlotNumber;
}
public boolean getStaffPark()
{
return staffPark;
}
public void setStaffPark(boolean newStaffPark)
{
staffPark = newStaffPark;
}
public Car getCar()
{
return car;
}
public void parkCar(Car car)
{
this.car = car;
}
public void removeCar()
{
car = null;
}
public boolean hasCar()
{
return this.car != null;
}
public String toString()
{
//String staffOrVisitor = "] [ Staff Park ] ";
String staffOrVisitor = "Park: ";
String taken = "is taken";
if (staffPark == false)
{
//staffOrVisitor = "] [Visitor Park] ";
staffOrVisitor = "Park: ";
}
if (car == null)
{
taken = " [vacant]";
}
else
{
taken = " contains vehicle, registration [" + car.getRego() + "]";
}
return staffOrVisitor + slotNumber + taken;
// return "Park [" + slotNumber + staffOrVisitor + taken;
}
}
public class Car {
// instance variables
private String rego;
private String name;
private boolean staff;
public Car(String rego, String name, boolean staff)
{
this.rego = rego;
this.name = name;
this.staff = staff;
}
public String toString()
{
return "Registration " + rego + " - Name: " + name + " - Staff member: " + staff;
}
public String getRego(){
return rego;
}
public void setRego(String newRego){
rego = newRego;
}
public String getName(){
return name;
}
public void setName(String newName){
name = newName;
}
public boolean getStaff(){
return staff;
}
public void setStaff(boolean newStaff){
staff = newStaff;
}
}
同样,问题在于创建模型并以某种方式将其绑定到您的视图(GUI)。最好是在这两个 类 或 类 组之间创建并保持良好的分离,但为了在这种情况下使事情更简单,我们可以在 GUI 中组合它们。为了向您展示我的意思,考虑一下您的代码的这种简化,它使用非常简单的 Car 和 ParkingSlot 类:
public class Car {
private String name;
public Car(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Car: " + name;
}
}
public class ParkingSlot {
private Car car;
private String name;
public ParkingSlot(String name) {
this.name = name;
}
public void setCar(Car car) {
this.car = car;
}
public Car getCar() {
return car;
}
public void clear() {
car = null;
}
public String getName() {
return name;
}
@Override
public String toString() {
String value = "Slot: " + name + "; ";
if (car == null) {
value += "empty";
} else {
value += car.toString();
}
return value;
}
}
我想要一个将 String 绑定到 ParkingSlot 的模型,为此,最好使用 Map<String, ParkingSlot>
。这是一个包含 ParkingSlot 对象并使它们可以通过插槽的“名称”String 访问的集合。我经常将它初始化为 new HashMap<String, ParkingSlot>()
,但我也想维护 Map 中的插入顺序,这样如果我遍历它,它就不会以某种随机顺序(因为 HashMap 往往是),所以,我将使用 LinkedHashMap<String, ParkingSlot>
对其进行初始化,因为这就像 HashMap 但保留了插入顺序:
private Map<String, ParkingSlot> slotMap = new LinkedHashMap<>();
因此,如果稍后我想遍历集合,显示 ParkingSlot 对象的状态,我可以简单地使用 for 循环:
for (Entry<String, ParkingSlot> entry : slotMap.entrySet()) {
System.out.printf("%s%n", entry.getValue());
}
因此,现在在创建 JButton 网格时,使用定义插槽的字符串将其与 ParkingSlot 对象的集合相关联。这可以是 Map
的 key
,也可以通过使用它来设置按钮的 actionCommand 与 JButton 相关联,每个按钮都带有一个字符串:
JPanel gridPanel = new JPanel(new GridLayout(0, 1));
for (int i = 0; i < slotCount; i++) {
String slotName = String.format("V%03d", i);
ParkingSlot slot = new ParkingSlot(slotName);
slotMap.put(slotName, slot);
JButton button = new JButton(slotName + ": Empty");
button.setActionCommand(slotName);
button.addActionListener(e -> parkingSlotButtonAction(e));
gridPanel.add(button);
}
当任意一个按钮被按下时,调用parkingSlotButtonAction(ActionEvent e)
方法,调用参数e.getSource()
获取源JButton,调用e.getSource()
获取按钮的actionCommand =24=] 在同一个参数上。它可以使用 slotMap
:
private void parkingSlotButtonAction(ActionEvent e) {
String slotName = e.getActionCommand();
JButton source = (JButton) e.getSource();
ParkingSlot slot = slotMap.get(slotName);
// .....
}
一个完整的简单示例如下所示:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.*;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.*;
import javax.swing.event.ChangeListener;
public class SimpleLotMain {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
LotGui gui = new LotGui(20);
JFrame frame = new JFrame("Lot");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(gui);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
@SuppressWarnings("serial")
class LotGui extends JPanel {
private Map<String, ParkingSlot> slotMap = new LinkedHashMap<>();
public LotGui(int slotCount) {
JPanel gridPanel = new JPanel(new GridLayout(0, 1));
for (int i = 0; i < slotCount; i++) {
String slotName = String.format("V%03d", i);
ParkingSlot slot = new ParkingSlot(slotName);
slotMap.put(slotName, slot);
JButton button = new JButton(slotName + ": Empty");
button.setActionCommand(slotName);
button.addActionListener(e -> parkingSlotButtonAction(e));
gridPanel.add(button);
}
JScrollPane scrollPane = new JScrollPane(gridPanel);
scrollPane.getViewport().setPreferredSize(new Dimension(400, 400));
JButton displaySlotsBtn = new JButton("Display Parking Spots");
displaySlotsBtn.addActionListener(e -> displaySlots());
JPanel bottomPanel = new JPanel();
bottomPanel.add(displaySlotsBtn);
setLayout(new BorderLayout());
add(scrollPane);
add(bottomPanel, BorderLayout.PAGE_END);
}
private void parkingSlotButtonAction(ActionEvent e) {
String slotName = e.getActionCommand();
JButton source = (JButton) e.getSource();
ParkingSlot slot = slotMap.get(slotName);
// JOptionPane to query whether to add/remove car
String carName = JOptionPane.showInputDialog("Enter Name of Car to Add");
// if the user cancels the dialog or enters only white-space text: exit
if (carName == null || carName.trim().isEmpty()) {
return;
}
// else, use the name
Car car = new Car(carName);
slot.setCar(car);
String text = slotName + ": " + carName;
source.setText(text);
}
private void displaySlots() {
for (Entry<String, ParkingSlot> entry : slotMap.entrySet()) {
System.out.printf("%s%n", entry.getValue());
}
}
}
//class SLot {
// List<ParkingSlot> slots = new ArrayList<>();
//
// public SLot(int carCount) {
// for (int i = 0; i < carCount; i++) {
// String name = String.format("S%03d", i);
// slots.add(new ParkingSlot(name));
// }
// }
//
// @Override
// public String toString() {
// return "SLot [slots=" + slots + "]";
// }
//
// public void addChangeListener(ChangeListener l) {
//
// }
//}
class Car {
private String name;
public Car(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Car: " + name;
}
}
class ParkingSlot {
private Car car;
private String name;
public ParkingSlot(String name) {
this.name = name;
}
public void setCar(Car car) {
this.car = car;
}
public Car getCar() {
return car;
}
public void clear() {
car = null;
}
public String getName() {
return name;
}
@Override
public String toString() {
String value = "Slot: " + name + "; ";
if (car == null) {
value += "empty";
} else {
value += car.toString();
}
return value;
}
}