forked from KNEMC/KLALB
✨ feat: 新增设备信息与额外路由设置,支持设备名广播及TUN显式禁用
- 设置页新增设备名称(单行)、设备描述(多行)、额外路由(CIDR列表)设置项 - RouterInfo 广播携带 deviceName,并在拓扑图节点与节点概览中展示;deviceDescription 保持本地概览显示 - 拓扑图节点标签支持多行文本绘制 - 节点概览面板新增 IP 地址及设备详情展示 - 支持将 TUNName 设为 null/"null"/空字符串时完全跳过 Wintun 虚拟网卡创建 - .classpath 容器改为标准 JavaSE-25 执行环境以同时兼容 JDK 25 与 26 - 新增 AGENTS.md 与 VS Code 调试及运行配置 BREAKING CHANGE: RouterInfo 在序列化末尾追加了 deviceName 字段(writeUTF),新旧版本节点混连时路由协议解析异常,需同步升级
This commit is contained in:
@@ -637,6 +637,7 @@ public class KLALBController {
|
||||
srv6Router = new SRv6Router(selfx, clock);
|
||||
if(configItem!=null) {
|
||||
srv6Router.setPerformanceStrategy(PerformanceStrategy.fromDescription(configItem.getPerformanceStrategy()));
|
||||
srv6Router.setDeviceName(configItem.getDeviceName());
|
||||
}
|
||||
srv6Router.runKLALBRouteProtocol();
|
||||
routingProtocol = srv6Router.getKlalbRouteProtol();
|
||||
@@ -647,10 +648,11 @@ public class KLALBController {
|
||||
System.out.println(" Loaded: SRv6 Stack");
|
||||
|
||||
String name=(configItem!=null)?configItem.getTUNName():CONST.KLALB_S_RV6;
|
||||
if (enableVirtualAdapter&&(name!=null)) {
|
||||
boolean enableTUN = enableVirtualAdapter && (name != null) && !name.trim().isEmpty() && !name.trim().equalsIgnoreCase("null");
|
||||
if (enableTUN) {
|
||||
Thread t=new Thread(()->{
|
||||
try {
|
||||
IPv6TUNLoopbackNetworkLink tunlink = new IPv6TUNLoopbackNetworkLink(name,
|
||||
IPv6TUNLoopbackNetworkLink tunlink = new IPv6TUNLoopbackNetworkLink(name.trim(),
|
||||
new IPv6AddressGroup(srv6Router.getLocator().getAddress(), 32), SRv6Router.MTU, dnsAddresses);
|
||||
tunlink.setMonitor(datatMonitor);
|
||||
// srv6Router.getLinkTabel().add(tunlink);
|
||||
@@ -664,7 +666,7 @@ public class KLALBController {
|
||||
});
|
||||
t.start();
|
||||
}else {
|
||||
System.out.println(" Tun Adapter Disbaled");
|
||||
System.out.println(" Tun Adapter Disabled");
|
||||
|
||||
}
|
||||
udpr=new UDPProtocolRegister(this);
|
||||
|
||||
@@ -19,6 +19,7 @@ public class KLALBControllerConfigItem extends KLALBConfigItem {
|
||||
private List<MultiProtocolSocketAddress>LineTable=new ArrayList<>();
|
||||
private List<MultiProtocolSocketAddress>ConnectLineTable=new ArrayList<>();
|
||||
private List<MultiProtocolSocketAddress>ntpServerTable=new ArrayList<>();
|
||||
private List<String>ExtraRoutes=new ArrayList<>();
|
||||
private boolean denyLineTableQuery=false;
|
||||
private boolean denyLineTableBroadcast=false;
|
||||
private String congestionAlgorithm="BBR";
|
||||
@@ -30,6 +31,8 @@ public class KLALBControllerConfigItem extends KLALBConfigItem {
|
||||
private int linkConnectionsCount=1;
|
||||
private String TUNName=CONST.KLALB_S_RV6;
|
||||
private String performanceStrategy="multifill";
|
||||
private String DeviceName;
|
||||
private String DeviceDescription;
|
||||
|
||||
public String getPerformanceStrategy() {
|
||||
return performanceStrategy;
|
||||
@@ -39,6 +42,22 @@ public class KLALBControllerConfigItem extends KLALBConfigItem {
|
||||
this.performanceStrategy = performanceStrategy;
|
||||
}
|
||||
|
||||
public String getDeviceName() {
|
||||
return DeviceName;
|
||||
}
|
||||
|
||||
public void setDeviceName(String deviceName) {
|
||||
DeviceName = deviceName;
|
||||
}
|
||||
|
||||
public String getDeviceDescription() {
|
||||
return DeviceDescription;
|
||||
}
|
||||
|
||||
public void setDeviceDescription(String deviceDescription) {
|
||||
DeviceDescription = deviceDescription;
|
||||
}
|
||||
|
||||
public void setNetworkInterfaceExcepts(List<String> networkInterfaceExcepts) {
|
||||
NetworkInterfaceExcepts = networkInterfaceExcepts;
|
||||
}
|
||||
@@ -193,6 +212,14 @@ public class KLALBControllerConfigItem extends KLALBConfigItem {
|
||||
this.ntpServerTable = ntpServerTable;
|
||||
}
|
||||
|
||||
public List<String> getExtraRoutes() {
|
||||
return ExtraRoutes;
|
||||
}
|
||||
|
||||
public void setExtraRoutes(List<String> extraRoutes) {
|
||||
ExtraRoutes = extraRoutes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -328,6 +355,7 @@ public class KLALBControllerConfigItem extends KLALBConfigItem {
|
||||
", LineTable=" + LineTable +
|
||||
", ConnectLineTable=" + ConnectLineTable +
|
||||
", ntpServerTable=" + ntpServerTable +
|
||||
", ExtraRoutes=" + ExtraRoutes +
|
||||
", denyLineTableQuery=" + denyLineTableQuery +
|
||||
", denyLineTableBroadcast=" + denyLineTableBroadcast +
|
||||
", congestionAlgorithm='" + congestionAlgorithm + '\'' +
|
||||
@@ -339,6 +367,8 @@ public class KLALBControllerConfigItem extends KLALBConfigItem {
|
||||
", linkConnectionsCount=" + linkConnectionsCount +
|
||||
", TUNName='" + TUNName + '\'' +
|
||||
", performanceStrategy='" + performanceStrategy + '\'' +
|
||||
", DeviceName='" + DeviceName + '\'' +
|
||||
", DeviceDescription='" + DeviceDescription + '\'' +
|
||||
", NetworkInterfaceExcepts=" + NetworkInterfaceExcepts +
|
||||
'}';
|
||||
}
|
||||
@@ -348,11 +378,11 @@ public class KLALBControllerConfigItem extends KLALBConfigItem {
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
KLALBControllerConfigItem that = (KLALBControllerConfigItem) o;
|
||||
return nogui == that.nogui && denyLineTableQuery == that.denyLineTableQuery && denyLineTableBroadcast == that.denyLineTableBroadcast && Double.compare(burstLimit, that.burstLimit) == 0 && Double.compare(delayUpperBound, that.delayUpperBound) == 0 && Double.compare(delayLowerBound, that.delayLowerBound) == 0 && nagleDelayTime == that.nagleDelayTime && linkNagleDelayTime == that.linkNagleDelayTime && linkConnectionsCount == that.linkConnectionsCount && Objects.equals(language, that.language) && Objects.equals(VirtualAddress, that.VirtualAddress) && Objects.equals(VirtualASN, that.VirtualASN) && Objects.equals(DNS, that.DNS) && Objects.equals(TCPListen, that.TCPListen) && Objects.equals(UDPListen, that.UDPListen) && Objects.equals(VirtualSocketName, that.VirtualSocketName) && Objects.equals(LineTable, that.LineTable) && Objects.equals(ConnectLineTable, that.ConnectLineTable) && Objects.equals(ntpServerTable, that.ntpServerTable) && Objects.equals(congestionAlgorithm, that.congestionAlgorithm) && Objects.equals(TUNName, that.TUNName) && Objects.equals(performanceStrategy, that.performanceStrategy) && Objects.equals(NetworkInterfaceExcepts, that.NetworkInterfaceExcepts);
|
||||
return nogui == that.nogui && denyLineTableQuery == that.denyLineTableQuery && denyLineTableBroadcast == that.denyLineTableBroadcast && Double.compare(burstLimit, that.burstLimit) == 0 && Double.compare(delayUpperBound, that.delayUpperBound) == 0 && Double.compare(delayLowerBound, that.delayLowerBound) == 0 && nagleDelayTime == that.nagleDelayTime && linkNagleDelayTime == that.linkNagleDelayTime && linkConnectionsCount == that.linkConnectionsCount && Objects.equals(language, that.language) && Objects.equals(VirtualAddress, that.VirtualAddress) && Objects.equals(VirtualASN, that.VirtualASN) && Objects.equals(DNS, that.DNS) && Objects.equals(TCPListen, that.TCPListen) && Objects.equals(UDPListen, that.UDPListen) && Objects.equals(VirtualSocketName, that.VirtualSocketName) && Objects.equals(LineTable, that.LineTable) && Objects.equals(ConnectLineTable, that.ConnectLineTable) && Objects.equals(ntpServerTable, that.ntpServerTable) && Objects.equals(ExtraRoutes, that.ExtraRoutes) && Objects.equals(congestionAlgorithm, that.congestionAlgorithm) && Objects.equals(TUNName, that.TUNName) && Objects.equals(performanceStrategy, that.performanceStrategy) && Objects.equals(DeviceName, that.DeviceName) && Objects.equals(DeviceDescription, that.DeviceDescription) && Objects.equals(NetworkInterfaceExcepts, that.NetworkInterfaceExcepts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), language, nogui, VirtualAddress, VirtualASN, DNS, TCPListen, UDPListen, VirtualSocketName, LineTable, ConnectLineTable, ntpServerTable, denyLineTableQuery, denyLineTableBroadcast, congestionAlgorithm, burstLimit, delayUpperBound, delayLowerBound, nagleDelayTime, linkNagleDelayTime, linkConnectionsCount, TUNName, performanceStrategy, NetworkInterfaceExcepts);
|
||||
return Objects.hash(super.hashCode(), language, nogui, VirtualAddress, VirtualASN, DNS, TCPListen, UDPListen, VirtualSocketName, LineTable, ConnectLineTable, ntpServerTable, ExtraRoutes, denyLineTableQuery, denyLineTableBroadcast, congestionAlgorithm, burstLimit, delayUpperBound, delayLowerBound, nagleDelayTime, linkNagleDelayTime, linkConnectionsCount, TUNName, performanceStrategy, DeviceName, DeviceDescription, NetworkInterfaceExcepts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,27 @@ public class KLALBUtils {
|
||||
v[3] = 0x01;
|
||||
return IPv6Address.valueOf(v);
|
||||
}
|
||||
|
||||
public static String parseCidr(String cidr) {
|
||||
int idx = cidr.indexOf('/');
|
||||
if (idx <= 0 || idx == cidr.length() - 1)
|
||||
throw new IllegalArgumentException("not a cidr: " + cidr);
|
||||
int prefix;
|
||||
try {
|
||||
prefix = Integer.parseInt(cidr.substring(idx + 1));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("bad prefix: " + cidr);
|
||||
}
|
||||
try {
|
||||
InetAddress addr = InetAddress.getByName(cidr.substring(0, idx));
|
||||
int max = (addr instanceof Inet6Address) ? 128 : 32;
|
||||
if (prefix < 0 || prefix > max)
|
||||
throw new IllegalArgumentException("prefix out of range: " + cidr);
|
||||
return addr.getHostAddress() + "/" + prefix;
|
||||
} catch (UnknownHostException e) {
|
||||
throw new IllegalArgumentException("bad address: " + cidr);
|
||||
}
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
System.out.println(uuidToIP(new UUID(-1,-1)));
|
||||
}
|
||||
|
||||
@@ -346,7 +346,16 @@ public class GraphPanel extends JPanel {
|
||||
g.setFont(UIEnv.getFont().deriveFont(10.0f));
|
||||
|
||||
//g.drawString(text, (int)(x+nodesize/2), (int)(y-nodesize/3));
|
||||
g.drawString(text, (int)(x-image.getWidth(null)/2-10), (int)(y+image.getHeight(null)/2+10));
|
||||
int imgw=(image!=null)?image.getWidth(null):(int)nodesize;
|
||||
int imgh=(image!=null)?image.getHeight(null):(int)nodesize;
|
||||
java.awt.FontMetrics fm=g.getFontMetrics();
|
||||
int lineHeight=fm.getHeight()+2;
|
||||
int textx=(int)(x-imgw/2-10);
|
||||
int texty=(int)(y+imgh/2+10)+fm.getAscent();
|
||||
String[] lines=text.split("\n");
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
g.drawString(lines[i], textx, texty+i*lineHeight);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 getPositionVec2() {
|
||||
|
||||
@@ -80,6 +80,10 @@ public class KLALBStateGUI3 extends XFrame {
|
||||
private JTextField textFieldLocate; // 定位地址输入框
|
||||
private JTextField asnField2; // ASN显示框
|
||||
private JTextArea dnsAreaSet; // DNS服务器设置区域
|
||||
private JTextArea extraRoutesSet; // 额外路由设置区域
|
||||
private JTextField deviceNameSet; // 设备名称设置框
|
||||
private JTextArea deviceDescriptionSet; // 设备描述设置区域
|
||||
private KLALBController kcontroller; // 关联的控制器
|
||||
private JComboBox<PerformanceStrategyItem> comboPerformance; // 性能策略选择框
|
||||
private JComboBox comboCongestion; // 拥塞控制算法选择框
|
||||
private JTextField tcpListeningSet; // TCP监听设置
|
||||
@@ -138,6 +142,7 @@ public class KLALBStateGUI3 extends XFrame {
|
||||
* 初始化UI界面
|
||||
*/
|
||||
private void initUI(KLALBController kc, String title) {
|
||||
kcontroller = kc;
|
||||
// 设置窗口基本属性
|
||||
setIconImage(UIEnv.getIcon());
|
||||
setTitleColor(UIEnv.getDefaultTitleColor());
|
||||
@@ -785,12 +790,30 @@ public class KLALBStateGUI3 extends XFrame {
|
||||
addressFieldSet = addr6.getTextField();
|
||||
settings.getView().add(addr6);
|
||||
|
||||
// 设备名称设置
|
||||
TextSettingItem deviceName = new TextSettingItem(UIEnv.getRsb().getString("devicename"),
|
||||
CONST.itemwidth, CONST.settingheight);
|
||||
deviceNameSet = deviceName.getTextField();
|
||||
settings.getView().add(deviceName);
|
||||
|
||||
// 设备描述设置
|
||||
TextAreaSettingItem deviceDescription = new TextAreaSettingItem(UIEnv.getRsb().getString("devicedescription"),
|
||||
CONST.itemwidth, CONST.settingheight * 5);
|
||||
deviceDescriptionSet = deviceDescription.getTextArea();
|
||||
settings.getView().add(deviceDescription);
|
||||
|
||||
// DNS服务器设置
|
||||
TextAreaSettingItem dns = new TextAreaSettingItem(UIEnv.getRsb().getString("dnsserver"),
|
||||
CONST.itemwidth, CONST.settingheight * 5);
|
||||
dnsAreaSet = dns.getTextArea();
|
||||
settings.getView().add(dns);
|
||||
|
||||
// 额外路由设置
|
||||
TextAreaSettingItem extraRoutes = new TextAreaSettingItem(UIEnv.getRsb().getString("extraroutes"),
|
||||
CONST.itemwidth, CONST.settingheight * 5);
|
||||
extraRoutesSet = extraRoutes.getTextArea();
|
||||
settings.getView().add(extraRoutes);
|
||||
|
||||
// ASN设置
|
||||
TextSettingItem asn = new TextSettingItem(UIEnv.getRsb().getString("asnumber"),
|
||||
CONST.itemwidth, CONST.settingheight);
|
||||
@@ -1022,6 +1045,26 @@ public class KLALBStateGUI3 extends XFrame {
|
||||
|
||||
kck.setNogui(nogui.isSelected());
|
||||
|
||||
// 保存设备名称
|
||||
String dnametext = deviceNameSet.getText().trim();
|
||||
if (dnametext.equals("")) {
|
||||
kck.setDeviceName(null);
|
||||
} else {
|
||||
kck.setDeviceName(dnametext);
|
||||
}
|
||||
if (kcontroller != null && kcontroller.getIpv6Router() != null) {
|
||||
kcontroller.getIpv6Router().setDeviceName(kck.getDeviceName());
|
||||
}
|
||||
|
||||
// 保存设备描述
|
||||
String ddesctext = deviceDescriptionSet.getText().trim();
|
||||
if (ddesctext.equals("")) {
|
||||
kck.setDeviceDescription(null);
|
||||
} else {
|
||||
kck.setDeviceDescription(ddesctext);
|
||||
}
|
||||
|
||||
|
||||
// 保存IPv6地址
|
||||
String ttext = addressFieldSet.getText().trim();
|
||||
if (ttext.equals("")) {
|
||||
@@ -1058,6 +1101,24 @@ public class KLALBStateGUI3 extends XFrame {
|
||||
}
|
||||
kck.setDNS(iaddr);
|
||||
|
||||
// 保存额外路由列表
|
||||
String[] spltEr = extraRoutesSet.getText().split("\n");
|
||||
List<String> eroutes = new ArrayList<>();
|
||||
for (String str : spltEr) {
|
||||
str = str.trim();
|
||||
if (!str.isEmpty()) {
|
||||
try {
|
||||
eroutes.add(KLALBUtils.parseCidr(str));
|
||||
} catch (RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
JOptionPane.showMessageDialog(this, UIEnv.getRsb().getString("invaildextraroutes"),
|
||||
UIEnv.getRsb().getString("warning"), JOptionPane.WARNING_MESSAGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
kck.setExtraRoutes(eroutes);
|
||||
|
||||
// 保存ASN
|
||||
String asntext = asnFieldSet.getText();
|
||||
if (asntext.equals("")) {
|
||||
@@ -1073,8 +1134,8 @@ public class KLALBStateGUI3 extends XFrame {
|
||||
}
|
||||
}
|
||||
|
||||
String tunNameText=tunDeviceName.getText();
|
||||
if(tunNameText.equals("")) {
|
||||
String tunNameText=tunDeviceName.getText().trim();
|
||||
if(tunNameText.equals("") || tunNameText.equalsIgnoreCase("null")) {
|
||||
kck.setTUNName(null);
|
||||
}else {
|
||||
kck.setTUNName(tunNameText);
|
||||
@@ -1453,6 +1514,14 @@ public class KLALBStateGUI3 extends XFrame {
|
||||
|
||||
nogui.setSelected( kck.isNogui());
|
||||
|
||||
// 加载设备名称
|
||||
String dname = kck.getDeviceName();
|
||||
deviceNameSet.setText(dname != null ? dname : "");
|
||||
|
||||
// 加载设备描述
|
||||
String ddesc = kck.getDeviceDescription();
|
||||
deviceDescriptionSet.setText(ddesc != null ? ddesc : "");
|
||||
|
||||
// 加载IPv6地址
|
||||
String vaddr = kck.getVirtualAddress();
|
||||
addressFieldSet.setText(vaddr != null ? vaddr : "");
|
||||
@@ -1461,6 +1530,10 @@ public class KLALBStateGUI3 extends XFrame {
|
||||
List<InetAddress> dns = kck.getDNS();
|
||||
dnsAreaSet.setText(listToStr(dns));
|
||||
|
||||
// 加载额外路由
|
||||
List<String> ers = kck.getExtraRoutes();
|
||||
extraRoutesSet.setText(listToStr2(ers));
|
||||
|
||||
// 加载ASN
|
||||
Long vasn = kck.getVirtualASN();
|
||||
asnFieldSet.setText(vasn != null ? vasn.toString() : "");
|
||||
|
||||
@@ -47,7 +47,7 @@ public class NetworkGraphPanel extends GraphPanel {
|
||||
}
|
||||
|
||||
public InetGraphNode(IPv6Address address, Color color, double x, double y, boolean ismarked) {
|
||||
super(getText(address), color, x, y, ismarked);
|
||||
super(getNodeText(address), color, x, y, ismarked);
|
||||
this.address=address;
|
||||
initign();
|
||||
}
|
||||
@@ -137,17 +137,33 @@ public class NetworkGraphPanel extends GraphPanel {
|
||||
return address2.toCompressedString();
|
||||
}
|
||||
|
||||
public void updateLabel() {
|
||||
setText(getNodeText(address));
|
||||
}
|
||||
|
||||
public IPv6Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(IPv6Address address) {
|
||||
this.address = address;
|
||||
super.setText(getText(address));
|
||||
super.setText(getNodeText(address));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 节点标签:显示广播得知的设备名称(若有)+IP地址
|
||||
*/
|
||||
private String getNodeText(IPv6Address address) {
|
||||
StringBuilder sb=new StringBuilder();
|
||||
String dname=controller.getIpv6Router().getKlalbRouteProtol().getDeviceName(address);
|
||||
if(dname!=null)
|
||||
sb.append(dname).append('\n');
|
||||
sb.append(InetGraphNode.getText(address));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private double nsPerPixel=1000L;
|
||||
private class InetGraphEdgeGroup extends GraphEdgeGroup{
|
||||
public InetGraphEdgeGroup(GraphNode nodeA, GraphNode nodeB) {
|
||||
@@ -178,6 +194,8 @@ public class NetworkGraphPanel extends GraphPanel {
|
||||
IPv6Address inet6Address = (IPv6Address) iterator.next();
|
||||
if(!addr.containsKey(inet6Address)) {
|
||||
iterator.remove();
|
||||
}else {
|
||||
((InetGraphNode)getNodes().get(inet6Address)).updateLabel();
|
||||
}
|
||||
}
|
||||
//System.out.println("------------------------------------");
|
||||
|
||||
@@ -10,10 +10,12 @@ import java.util.List;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
@@ -65,6 +67,27 @@ public class NodeInformationPanel extends JPanel {
|
||||
panel.setLayout(new BorderLayout(0, 0));
|
||||
tabbedPane.addTab(UIEnv.getRsb().getString("overview"), null, panel, null);
|
||||
|
||||
JTextArea overviewArea = new JTextArea();
|
||||
overviewArea.setEditable(false);
|
||||
overviewArea.setLineWrap(true);
|
||||
overviewArea.setWrapStyleWord(true);
|
||||
overviewArea.setFont(UIEnv.getFont().deriveFont(14.0f));
|
||||
overviewArea.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
|
||||
StringBuilder sb=new StringBuilder();
|
||||
sb.append(UIEnv.getRsb().getString("ipv6addr")).append(": ").append(address.toCompressedString()).append('\n');
|
||||
String dname=controller.getIpv6Router().getKlalbRouteProtol().getDeviceName(address);
|
||||
if(dname!=null) {
|
||||
sb.append('\n').append(UIEnv.getRsb().getString("devicename")).append(": ").append(dname).append('\n');
|
||||
}
|
||||
if(address.equals(controller.getIpv6Router().getLocator().getAddress())&&controller.getConfigItem()!=null) {
|
||||
String ddesc=controller.getConfigItem().getDeviceDescription();
|
||||
if(ddesc!=null&&!ddesc.isEmpty()) {
|
||||
sb.append('\n').append(UIEnv.getRsb().getString("devicedescription")).append(":\n").append(ddesc).append('\n');
|
||||
}
|
||||
}
|
||||
overviewArea.setText(sb.toString());
|
||||
panel.add(new JScrollPane(overviewArea), BorderLayout.CENTER);
|
||||
|
||||
JPanel panel_1 = new JPanel();
|
||||
panel_1.setLayout(new BorderLayout(0, 0));
|
||||
panel_1.add(scrollPane);
|
||||
|
||||
Reference in New Issue
Block a user