我正在尝试使用 Java 套接字制作一个简单的网络项目,其中客户端正在从拥有所有可用停车位的 ArrayList 的服务器预订停车位(通过图形用户界面)。 ParkingSpace 类包含 3 个属性: -车位ID -该坐标 -还有可用性
首先,客户端将按下 jButton1 以启动与服务器的连接并接收包含可用停车位的列表对象。 客户端 GUI 有一个 jTable,其中可以预览可用空间的 ID 和相应的坐标,以及一个 ComboBox,客户端可以在其中选择他想要的空间的 ID。一旦选择了空间,客户端将按下jButton2 将新更新的列表对象发送到服务器,所选空间可用性更改为 false。
只是提到服务器缺少将书籍接收到服务器的功能以及如何处理预订的空间,但我会在稍后阶段实现。
//CLASS ParkingSpace
package exams2013sockets;
import java.io.*;
/**
*
* @author Alexandros
*/
public class ParkingSpace implements Serializable {
private String id;
private String coordinates;
private boolean availability;
public ParkingSpace(String id, String coordinates, boolean availability) {
this.id = id;
this.coordinates = coordinates;
this.availability = availability;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCoordinates() {
return coordinates;
}
public void setCoordinates(String coordinates) {
this.coordinates = coordinates;
}
public boolean isAvailability() {
return availability;
}
public void setAvailability(boolean availability) {
this.availability = availability;
}
}
===========================================
//CLASS Server
package exams2013sockets;
import java.util.ArrayList;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Alexandros
*/
public class Server implements Serializable {
ServerSocket listenSocket;
Socket server;
ObjectInputStream ois;
ObjectOutputStream oos;
public void startServer() {
try {
listenSocket=new ServerSocket(7000);
while (true) {
server=listenSocket.accept();
OutputStream os=server.getOutputStream();
oos=new ObjectOutputStream(os);
InputStream is=server.getInputStream();
ois=new ObjectInputStream(is);
sendListToClient();
closeServer();
}
} catch (SocketException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void closeServer() {
try {
ois.close();
oos.close();
server.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public ArrayList listOfSpaces() {
ArrayList<ParkingSpace> list = new ArrayList<>();
ParkingSpace p1 = new ParkingSpace("A01","1,1",true);
ParkingSpace p2 = new ParkingSpace("A02","1,2",true);
ParkingSpace p3 = new ParkingSpace("A03","1,3",true);
ParkingSpace p4 = new ParkingSpace("A04","1,4",true);
ParkingSpace p5 = new ParkingSpace("A05","1,5",true);
ParkingSpace p6 = new ParkingSpace("A06","1,6",true);
ParkingSpace p7 = new ParkingSpace("A07","1,7",true);
ParkingSpace p8 = new ParkingSpace("A08","1,8",true);
ParkingSpace p9 = new ParkingSpace("A09","1,9",true);
ParkingSpace p10 = new ParkingSpace("A10","1,10",true);
ParkingSpace p11 = new ParkingSpace("B01","2,1",true);
ParkingSpace p12 = new ParkingSpace("B02","2,2",true);
ParkingSpace p13 = new ParkingSpace("B03","2,3",true);
ParkingSpace p14 = new ParkingSpace("B04","2,4",true);
ParkingSpace p15 = new ParkingSpace("B05","2,5",true);
ParkingSpace p16 = new ParkingSpace("B06","2,6",true);
ParkingSpace p17 = new ParkingSpace("B07","2,7",true);
ParkingSpace p18 = new ParkingSpace("B08","2,8",true);
ParkingSpace p19 = new ParkingSpace("B09","2,9",true);
ParkingSpace p20 = new ParkingSpace("B10","2,10",true);
list.add(p1);list.add(p2);list.add(p3);
list.add(p4);list.add(p5);list.add(p6);
list.add(p7);list.add(p8);list.add(p9);
list.add(p10);list.add(p11);list.add(p12);
list.add(p13);list.add(p14);list.add(p15);
list.add(p16);list.add(p17);list.add(p18);
list.add(p19);list.add(p20);
return list;
}
public void sendListToClient() {
try {
oos.writeObject(listOfSpaces());
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) {
Server serv=new Server();
serv.startServer();
}
}
==========================================
//CLASS Client
package exams2013sockets;
import java.util.ArrayList;
import javax.swing.table.DefaultTableModel;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Alexandros
*/
public class Client extends javax.swing.JFrame {
Socket client;
ObjectInputStream ois;
ObjectOutputStream oos;
private ArrayList<ParkingSpace> serverList;
private ArrayList<ParkingSpace> updatedList;
/**
* Creates new form Client
*/
public Client() {
initComponents();
}
public void startClient() {
try {
client=new Socket("127.0.0.1", 7000);
OutputStream os=client.getOutputStream();
oos=new ObjectOutputStream(os);
InputStream is=client.getInputStream();
ois=new ObjectInputStream(is);
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void closeClient() {
try {
ois.close();
oos.close();
client.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void addRowsToTable(ArrayList<ParkingSpace> paramList){
DefaultTableModel model = (DefaultTableModel) jTable2.getModel();
serverList.addAll(paramList);
Object rowData[] = new Object[20];
for (int i=0; i<serverList.size(); i++) {
if (serverList.get(i).isAvailability()==true) {
rowData[0] = serverList.get(i).getId();
rowData[1] = serverList.get(i).getCoordinates();
model.addRow(rowData); }
}
}
public void addOptionsToComboBox(){
for (int i=0; i<jTable2.getRowCount(); i++) {
jComboBox1.addItem(jTable2.getValueAt(i,0).toString());
}
}
public void bookSpace(ArrayList<ParkingSpace> paramList){
updatedList.addAll(paramList);
Object selectedItem = jComboBox1.getSelectedItem();
for (int i=0; i<updatedList.size(); i++) {
if (updatedList.get(i).getId().equals(selectedItem.toString())) {
updatedList.get(i).setAvailability(false);
}
}
}
public void UpdateListToServer() {
try {
oos.writeObject(updatedList);
closeClient();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane2 = new javax.swing.JScrollPane();
jTable2 = new javax.swing.JTable();
jComboBox1 = new javax.swing.JComboBox<>();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jTable2.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"ID", "Coordinates"
}
) {
boolean[] canEdit = new boolean [] {
false, false
};
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
jScrollPane2.setViewportView(jTable2);
jComboBox1.setMaximumRowCount(21);
jComboBox1.setToolTipText("");
jButton1.setText("Available Positions");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
jButton2.setText("Select Position");
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 213, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 126, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jButton2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(99, 99, 99))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(39, 39, 39)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 364, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(23, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(90, 90, 90))))
);
pack();
}// </editor-fold>
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
/*Receive the list object from the server and fill the jTable with the available spaces */
ArrayList<ParkingSpace> recvFromServ = null;
try {
recvFromServ =(ArrayList<ParkingSpace>)ois.readObject();
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
addRowsToTable(recvFromServ);
addOptionsToComboBox();
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
// Button to select the Space and make it unavailable
bookSpace(serverList);
UpdateListToServer();
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(() -> {
new Client().setVisible(true);
});
Client cl=new Client();
cl.startClient();
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JComboBox<String> jComboBox1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTable jTable2;
// End of variables declaration
}
启动客户端时出现的错误是:
Exception in thread "main" java.lang.NullPointerException
at javax.swing.plaf.nimbus.NimbusStyle.validate(NimbusStyle.java:298)
at javax.swing.plaf.nimbus.NimbusStyle.getValues(NimbusStyle.java:806)
at javax.swing.plaf.nimbus.NimbusStyle.getInsets(NimbusStyle.java:485)
at javax.swing.plaf.synth.SynthStyle.installDefaults(SynthStyle.java:913)
at javax.swing.plaf.synth.SynthLookAndFeel.updateStyle(SynthLookAndFeel.java:265)
at javax.swing.plaf.synth.SynthRootPaneUI.updateStyle(SynthRootPaneUI.java:93)
at javax.swing.plaf.synth.SynthRootPaneUI.installDefaults(SynthRootPaneUI.java:59)
at javax.swing.plaf.basic.BasicRootPaneUI.installUI(BasicRootPaneUI.java:56)
at javax.swing.JComponent.setUI(JComponent.java:660)
at javax.swing.JRootPane.setUI(JRootPane.java:474)
at javax.swing.JRootPane.updateUI(JRootPane.java:484)
at javax.swing.JRootPane.<init>(JRootPane.java:371)
at javax.swing.JFrame.createRootPane(JFrame.java:286)
at javax.swing.JFrame.frameInit(JFrame.java:267)
at javax.swing.JFrame.<init>(JFrame.java:190)
at exams2013sockets.Client.<init>(Client.java:30)
at exams2013sockets.Client.main(Client.java:246)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.plaf.nimbus.NimbusStyle.validate(NimbusStyle.java:298)
at javax.swing.plaf.nimbus.NimbusStyle.installDefaults(NimbusStyle.java:227)
at javax.swing.plaf.synth.SynthStyle.installDefaults(SynthStyle.java:916)
at javax.swing.plaf.synth.SynthLookAndFeel.updateStyle(SynthLookAndFeel.java:265)
at javax.swing.plaf.synth.SynthScrollBarUI.updateStyle(SynthScrollBarUI.java:130)
at javax.swing.plaf.synth.SynthScrollBarUI.installDefaults(SynthScrollBarUI.java:67)
at javax.swing.plaf.basic.BasicScrollBarUI.installUI(BasicScrollBarUI.java:172)
at javax.swing.JComponent.setUI(JComponent.java:660)
at javax.swing.JScrollBar.setUI(JScrollBar.java:207)
at javax.swing.JScrollBar.updateUI(JScrollBar.java:227)
at javax.swing.JScrollBar.<init>(JScrollBar.java:161)
at javax.swing.JScrollBar.<init>(JScrollBar.java:176)
at javax.swing.JScrollPane$ScrollBar.<init>(JScrollPane.java:718)
at javax.swing.JScrollPane.createVerticalScrollBar(JScrollPane.java:873)
at javax.swing.JScrollPane.<init>(JScrollPane.java:299)
at javax.swing.JScrollPane.<init>(JScrollPane.java:351)
at exams2013sockets.Client.initComponents(Client.java:109)
at exams2013sockets.Client.<init>(Client.java:31)
at exams2013sockets.Client.lambda$main$0(Client.java:243)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
C:\Users\Alexandros\AppData\Local\NetBeans\Cache\12.5\executor-snippets\run.xml:111: The following error occurred while executing this line:
C:\Users\Alexandros\AppData\Local\NetBeans\Cache\12.5\executor-snippets\run.xml:94: Java returned: 1
BUILD FAILED (total time: 8 seconds)
据我了解,当引用尚未创建的对象时会发生 NullPointerException。但我创建的表单已自动生成代码。
如何处理??
PS:在项目的这个阶段,我想从服务器接收对象列表到客户端,并按下 jButton1 来预览 jTable 上的空间
这看起来像是 Swing 或任何相关组件(如生成器)中的错误。 通常它不应该发生在自动生成的项目中。
我在使用 Swing 的不同项目中找到了它的一些示例:
https://bz.apache.org/netbeans/show_bug.cgi?id=258559
https://github.com/FeraGroup/FTCVortexScoreCounter/issues/23
没有提到解决方法。 我认为值得一一尝试从您的表单/应用程序中删除组件/按钮,以了解导致此问题的原因。可能没有更简单的解决方案..
它必须与 GUI 的 UI 管理器做一些事情。在存在 GUI 的 Client 类的主体中,有设置“外观和感觉”的代码……但我还没有找到解决方法。
要验证这是否与外观有关,请从代码中删除
javax.swing.UIManager.setLookAndFeel(...)
并再次运行应用程序。你仍然看到问题吗?
从堆栈跟踪来看,这看起来像是与滚动条相关的问题,请检查您是否有任何使用滚动条或滚动窗格的组件。调查如果你改变它会发生什么。
使用不同的 JVM 尝试您的应用程序。甲骨文,OpenJDK,......无论你找到什么。
记得记下结果,它们对进一步排除故障很有价值
在我删除“Look and Feel”的代码后,与此错误相关的错误似乎消失了。
我现在得到的错误如下(包括一些连接问题):
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:75)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:476)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:218)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:200)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:162)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394)
at java.net.Socket.connect(Socket.java:606)
at java.net.Socket.connect(Socket.java:555)
at java.net.Socket.<init>(Socket.java:451)
at java.net.Socket.<init>(Socket.java:228)
at exams2013sockets.Client.startClient(Client.java:36)
at exams2013sockets.Client.main(Client.java:249)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at exams2013sockets.Client.jButton1ActionPerformed(Client.java:190)
at exams2013sockets.Client.access$000(Client.java:19)
at exams2013sockets.Client$2.actionPerformed(Client.java:141)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:262)
at java.awt.Component.processMouseEvent(Component.java:6539)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3318)
at java.awt.Component.processEvent(Component.java:6304)
at java.awt.Container.processEvent(Container.java:2239)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2297)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4904)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4535)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4476)
at java.awt.Container.dispatchEventImpl(Container.java:2283)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:84)
at java.awt.EventQueue$4.run(EventQueue.java:733)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)