📄 simparamrtable.java
字号:
/*
JaNetSim --- Java Network Simulator
-------------------------------------
This software was developed at the Network Research Lab, Faculty of
Computer Science and Information Technology (FCSIT), University of Malaya.
This software may be used and distributed freely. FCSIT assumes no responsibility
whatsoever for its use by other parties, and makes no guarantees, expressed or
implied, about its quality, reliability, or any other characteristic.
We would appreciate acknowledgement if the software is used.
FCSIT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
FROM THE USE OF THIS SOFTWARE.
*/
package janetsim.component;
import janetsim.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.math.BigInteger;
public class SimParamRTable extends SimParameter implements ActionListener,java.io.Serializable {
private class Route implements java.io.Serializable {
BigInteger nsap; //the NSAP (not only prefix)
int mask; //mask in number of bits (from 0 to 160)
SimComponent outcomp;
}
private java.util.List rtable;
private transient JComponent jcomp=null;
private transient SimDialog rtableDialog=null;
private transient JTable table=null;
public SimParamRTable(String aName,SimComponent comp,long creationTick,
SimComponent defaultgw) {
super(aName,comp,creationTick,false);
rtable=new java.util.ArrayList();
Route r=new Route();
r.nsap=new BigInteger("0");
r.mask=0;
r.outcomp=defaultgw;
rtable.add(r);
}
////////////// possible overrides //////////////////////////
public JComponent getJComponent() {
if(jcomp==null) {
jcomp=new JButton("Manage...");
((JButton)jcomp).setHorizontalAlignment(JButton.LEFT);
((JButton)jcomp).addActionListener(this);
}
return jcomp;
}
////////////// services /////////////////////////////////////
//return the correct outgoing component (well, should be a LINK),
//return null if no match and no default gateway,
//also return null if the given NSAP is invalid
public SimComponent queryOutLink(String NSAP) {
BigInteger nsap=null;
try {
nsap=new BigInteger(NSAP,16);
} catch (NumberFormatException ex) {
return null;
}
//perform longest match (the list is already sorted ;)
java.util.Iterator i=rtable.iterator();
while(i.hasNext()) {
Route r=(Route)i.next();
//create the actual mask
BigInteger mask=new BigInteger("1");
mask=mask.shiftLeft(r.mask).subtract(mask);
mask=mask.shiftLeft(160-r.mask).and(nsap);
if(mask.equals(r.nsap))
return r.outcomp;
}
return null;
}
////////////// private /////////////////////////////////////
private class DialogListener implements ActionListener {
private JTextField txtNSAP,txtMask;
private JComboBox comps;
private java.util.List neighbors;
DialogListener(JTextField n,JTextField m,
JComboBox c,java.util.List nbors) {
txtNSAP=n;
txtMask=m;
comps=c;
neighbors=nbors;
}
private boolean checkRunning() {
if(getOwner().getSim().isRunning()) {
JOptionPane.showMessageDialog(theGUI.getMainFrame(),"Simulation is running!",
"Command not allowed",JOptionPane.WARNING_MESSAGE);
return false;
}
return true;
}
public void actionPerformed(ActionEvent e) {
String command=e.getActionCommand();
if(command.equals("Add")) {
if(!checkRunning()) return;
//handle NSAP
String strnsap=txtNSAP.getText().trim();
if(strnsap.length()>40) {
JOptionPane.showMessageDialog(rtableDialog,"NSAP too long!","Error",
JOptionPane.INFORMATION_MESSAGE);
txtNSAP.requestFocus();
return;
}
BigInteger nsap=null;
try {
nsap=new BigInteger(strnsap,16);
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(rtableDialog,"Invalid NSAP!","Error",
JOptionPane.INFORMATION_MESSAGE);
txtNSAP.requestFocus();
return;
}
//next, the mask
String strmask=txtMask.getText().trim();
int mask=0;
try {
mask=Integer.parseInt(strmask);
} catch(NumberFormatException ex) {
JOptionPane.showMessageDialog(rtableDialog,
"Invalid mask (must be a integer 0-160)!","Error",
JOptionPane.INFORMATION_MESSAGE);
txtMask.requestFocus();
return;
}
if(mask<0 || mask>160) {
JOptionPane.showMessageDialog(rtableDialog,
"Invalid mask (must be a integer 0-160)!","Error",
JOptionPane.INFORMATION_MESSAGE);
txtMask.requestFocus();
return;
}
//check mask length vs. nsap
BigInteger testmask=new BigInteger("1");
testmask=testmask.shiftLeft(mask).subtract(testmask);
testmask=testmask.shiftLeft(160-mask).and(nsap);
if(!testmask.equals(nsap)) {
JOptionPane.showMessageDialog(rtableDialog,
"NSAP does not fit mask!","Error",
JOptionPane.INFORMATION_MESSAGE);
txtNSAP.requestFocus();
return;
}
//ok, now add it (binary search, sort descending by mask)
int left=0;
int right=rtable.size()-1;
int insertpoint=0;
while(left<=right) {
int middle=(left+right)/2;
if(mask==((Route)rtable.get(middle)).mask) {
do {
middle++;
if(middle==rtable.size()) break;
} while(mask==((Route)rtable.get(middle)).mask);
insertpoint=middle;
break;
}
if(mask < ((Route)rtable.get(middle)).mask) {
left=middle+1;
insertpoint=left;
}
else {
insertpoint=middle;
right=middle-1;
}
}
Route newroute=new Route();
newroute.nsap=nsap;
newroute.mask=mask;
newroute.outcomp=(SimComponent)neighbors.get(comps.getSelectedIndex());
rtable.add(insertpoint,newroute);
//finally, refresh the table
table.revalidate();
rtableDialog.repaint();
}
else if(command.equals("Remove")) {
if(!checkRunning()) return;
int [] sels=table.getSelectedRows();
java.util.List selcomps=new java.util.ArrayList();
for(int i=0;i<sels.length;i++)
selcomps.add(rtable.get(sels[i]));
rtable.removeAll(selcomps);
table.getSelectionModel().clearSelection();
table.revalidate();
rtableDialog.repaint();
}
else if(command.equals("Close")) {
rtableDialog.dispose();
}
}
}
//helper for generating the combobox contents
// and fill in the neighbor list
private String [] getOutLinks(java.util.List outlinks) {
int i;
for(i=0;i<getOwner().neighborCount();i++) {
if(getOwner().neighbor(i).getCompClass().equals("Link"))
outlinks.add(getOwner().neighbor(i));
}
String [] names=new String[outlinks.size()];
for(i=0;i<names.length;i++) {
names[i]=((SimComponent)outlinks.get(i)).getName();
}
return names;
}
//helper for monitoring changes in the simulation (e.g. to refresh table)
private void checkLinks() {
int i;
//check if there are still neighbors...
if(getOwner().neighborCount()==0) {
//remove all entries
rtable.clear();
if(rtableDialog!=null) rtableDialog.dispose();
return;
}
//check for removal of neighbors...
java.util.Iterator it=rtable.iterator();
while(it.hasNext()) {
Route r=(Route)it.next();
for(i=0;i<getOwner().neighborCount();i++) {
if(getOwner().neighbor(i)==r.outcomp) break;
}
if(i==getOwner().neighborCount())
it.remove();
}
//refresh dialog box if it's there...
if(rtableDialog!=null) {
rtableDialog.getContentPane().removeAll();
JComponent newpane=createNewRTableDialog();
rtableDialog.getContentPane().add(newpane);
newpane.revalidate();
}
}
//the table model
private class MyTableModel extends javax.swing.table.AbstractTableModel {
public int getRowCount() {
return rtable.size();
}
public int getColumnCount() {
return 3;
}
public Object getValueAt(int row,int col) {
switch(col) {
case 0:
return ((Route)rtable.get(row)).nsap.toString(16);
case 1:
return String.valueOf(((Route)rtable.get(row)).mask);
case 2:
return ((Route)rtable.get(row)).outcomp.getName();
}
return null;
}
public String getColumnName(int col) {
switch(col) {
case 0: return "NSAP (hex)";
case 1: return "Mask";
case 2: return "Out Link";
}
return "N/A";
}
}
private JComponent createNewRTableDialog() {
//prepare the input panel
JPanel inputPanel1=new JPanel();
inputPanel1.add(new JLabel("NSAP (hex):"));
JTextField nsap=new JTextField(20);
inputPanel1.add(nsap);
JPanel inputPanel2=new JPanel();
inputPanel2.add(new JLabel("Mask:"));
JTextField mask=new JTextField(4);
inputPanel2.add(mask);
inputPanel2.add(new JLabel("Out Links:"));
java.util.List outlinks=new java.util.ArrayList();
JComboBox comps=new JComboBox(getOutLinks(outlinks));
comps.setSelectedIndex(0);
inputPanel2.add(comps);
//prepare the table
table=new JTable(new MyTableModel());
JScrollPane scrollPane=new JScrollPane(table);
table.setPreferredScrollableViewportSize(new Dimension(400,100));
table.getColumnModel().getColumn(0).setPreferredWidth(250);
//prepare buttons panel
DialogListener listener=new DialogListener(nsap,mask,comps,outlinks);
JPanel compPanel=new JPanel();
JButton btnAdd=new JButton("Add");
btnAdd.addActionListener(listener);
compPanel.add(btnAdd);
JButton btnRemove=new JButton("Remove");
btnRemove.addActionListener(listener);
compPanel.add(btnRemove);
JButton btnClose=new JButton("Close");
btnClose.addActionListener(listener);
compPanel.add(btnClose);
//now the outer panel
JPanel outerpane=new JPanel();
GridBagLayout gl=new GridBagLayout();
outerpane.setLayout(gl);
GridBagConstraints gc=new GridBagConstraints();
gc.fill=GridBagConstraints.BOTH;
gc.gridx=0; gc.gridy=0;
gl.setConstraints(inputPanel1,gc);
outerpane.add(inputPanel1);
gc.gridy=1;
gl.setConstraints(inputPanel2,gc);
outerpane.add(inputPanel2);
gc.gridy=2;
gl.setConstraints(compPanel,gc);
outerpane.add(compPanel);
gc.gridy=3; gc.weightx=1; gc.weighty=1;
gl.setConstraints(scrollPane,gc);
outerpane.add(scrollPane);
return outerpane;
}
public void actionPerformed(ActionEvent e) {
if(rtableDialog==null) {
rtableDialog=new SimDialog(theGUI.getMainFrame(),getOwner().getName()
+" - "+getName(),getOwner().getSim(),theGUI) {
public void connectionsChanged() { checkLinks(); }
public void componentsChanged() { checkLinks(); }
};
rtableDialog.getContentPane().add(createNewRTableDialog());
rtableDialog.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
rtableDialog=null;
}
});
rtableDialog.pack();
Dimension dsize=rtableDialog.getSize();
Dimension scrsize=Toolkit.getDefaultToolkit().getScreenSize();
rtableDialog.setLocation((scrsize.width-dsize.width)/2,(scrsize.height-dsize.height)/2);
rtableDialog.show();
}
else
rtableDialog.requestFocus();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -