如何解决Java Swing GUI 创建 - 如何获取动态创建的按钮以正确更新
我的大学项目是为我为早期项目制作的停车场应用程序创建一个工作 GUI。
停车场由员工停车场和游客停车场组成,GUI 会根据用户想要添加的数量动态地为每个停车场创建按钮。
我遇到的问题是在我最初创建我的停车场并为员工/游客公园输入用户输入后,公园按预期显示,除了点击每个公园获取信息不起作用。
当我选择“添加汽车”选项时,无论我尝试将汽车添加到哪个位置,它只会更新最终的游客公园……例如,如果有 5 个工作人员和游客公园,并且我将汽车添加到插槽 S001,更改将反映在插槽 V005。
附注。我对编程很陌生,如果格式和逻辑不正确,请见谅。另外,我们必须使用名为 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),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,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.",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.",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.",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,"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,JOptionPane.informatION_MESSAGE );
return;
}
else
{
cp1.addParkingSlot(new ParkingSlot(slotNumber,staff,car));
JOptionPane.showMessageDialog(this,"Sucess! You have added slot: "
+ slotNumber,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",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 对象并使它们可以通过插槽的“名称”(字符串)访问的集合。我经常将它初始化为 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 对象的集合相关联。这可以是 key
的 Map
,也可以通过使用它来设置按钮的 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,并且可以通过调用{{1}来获取按钮的actionCommand }} 在同一个参数上。它可以通过使用 e.getActionCommand()
:
slotMap
一个完整的简单示例可能如下所示:
private void parkingSlotButtonAction(ActionEvent e) {
String slotName = e.getActionCommand();
JButton source = (JButton) e.getSource();
ParkingSlot slot = slotMap.get(slotName);
// .....
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。