From 9c5a81da25604959d60baa0c3b9985d9953e4275 Mon Sep 17 00:00:00 2001 From: SerinaNya <34389622+SerinaNya@users.noreply.github.com> Date: Sat, 22 Aug 2026 00:12:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(ui):=20=E8=AE=BE=E7=BD=AE=E9=A1=B5?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=90=AF=E7=94=A8/=E7=A6=81=E7=94=A8=20TUN?= =?UTF-8?q?=20=E5=B9=B6=E6=94=B9=E8=BF=9B=E9=BB=98=E8=AE=A4=E5=AD=97?= =?UTF-8?q?=E4=BD=93=E5=9B=9E=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 设置页新增「启用虚拟网卡 (TUN)」复选框;未启用时隐藏虚拟网卡名称输入框, 显示橙色警告"⚠️ TUNTAP 未启用:虚拟网卡未挂载",保存时写入 TUNName=null - 勾选后恢复名称输入框,留空自动填入默认值 KLALB_SRv6 - 控制台同步输出英文警告:禁用时 "WARNING: TUNTAP is disabled..."、 挂载失败时 "WARNING: Failed to mount TUN adapter..." - UIEnv 默认字体改为按平台探测回退: 雅黑/PingFang/Noto 等候选 → 系统 Label.font → Java Dialog 逻辑字体 --- src/klalb_en_US.properties | 2 + src/klalb_zh_CN.properties | 2 + .../cloud/network/klalb/KLALBController.java | 3 +- .../network/klalb/ui/KLALBStateGUI3.java | 61 ++++++++++++++++--- src/org/kne/cloud/network/klalb/ui/UIEnv.java | 29 ++++++++- 5 files changed, 85 insertions(+), 12 deletions(-) diff --git a/src/klalb_en_US.properties b/src/klalb_en_US.properties index 97ed089..84e2a5f 100644 --- a/src/klalb_en_US.properties +++ b/src/klalb_en_US.properties @@ -92,6 +92,8 @@ transmitnagledelaytime=Transmit nagle delay time linknagledelaytime=Link nagle delay time linkconnectionscount=Link connections count tunname=Virtual network device name +enabletun=Enable TUN device +tundisabledwarning=⚠️ TUNTAP is disabled: Virtual network device not mounted dashboard=Dashboard backplanedelay=Backplane delay backplanepps=Backplane PPS diff --git a/src/klalb_zh_CN.properties b/src/klalb_zh_CN.properties index c1257cd..2ae8e70 100644 --- a/src/klalb_zh_CN.properties +++ b/src/klalb_zh_CN.properties @@ -92,6 +92,8 @@ transmitnagledelaytime=传输粘包等待时间 linknagledelaytime=链路粘包等待时间 linkconnectionscount=链路连接数 tunname=虚拟网卡名称 +enabletun=启用虚拟网卡 (TUN) +tundisabledwarning=⚠️ TUNTAP 未启用:虚拟网卡未挂载 dashboard=仪表盘 backplanedelay=背板处理延迟 backplanepps=背板包转发率 diff --git a/src/org/kne/cloud/network/klalb/KLALBController.java b/src/org/kne/cloud/network/klalb/KLALBController.java index 3eb1857..1227296 100644 --- a/src/org/kne/cloud/network/klalb/KLALBController.java +++ b/src/org/kne/cloud/network/klalb/KLALBController.java @@ -661,12 +661,13 @@ public class KLALBController { } catch (Exception e) { System.err.println("挂载虚拟网卡失败,可能是无管理员权限?请尝试使用管理员权限运行软件"); + System.err.println("WARNING: Failed to mount TUN adapter (requires administrator privileges)"); e.printStackTrace(); } }); t.start(); }else { - System.out.println(" Tun Adapter Disabled"); + System.out.println(" WARNING: TUNTAP is disabled: Virtual network device not mounted"); } udpr=new UDPProtocolRegister(this); diff --git a/src/org/kne/cloud/network/klalb/ui/KLALBStateGUI3.java b/src/org/kne/cloud/network/klalb/ui/KLALBStateGUI3.java index 468c927..80f639d 100644 --- a/src/org/kne/cloud/network/klalb/ui/KLALBStateGUI3.java +++ b/src/org/kne/cloud/network/klalb/ui/KLALBStateGUI3.java @@ -98,6 +98,9 @@ public class KLALBStateGUI3 extends XFrame { private JCheckBox denyQuery; private ClosableTabbedPane tabbedPane; // 可关闭的标签页面板 private JCheckBox nogui; + private JCheckBox enableTun; + private TextSettingItem tunNameItem; + private SettingItem tunWarningItem; // ==================== 配置和回调 ==================== private KLALBConfig config; // 配置文件 @@ -820,10 +823,29 @@ public class KLALBStateGUI3 extends XFrame { asnFieldSet = asn.getTextField(); settings.getView().add(asn); - TextSettingItem tunName = new TextSettingItem(UIEnv.getRsb().getString("tunname"), + // 启用虚拟网卡 (TUN) + CheckBoxSettingItem enableTunc = new CheckBoxSettingItem(UIEnv.getRsb().getString("enabletun"), + CONST.itemwidth, CONST.settingheight); + enableTun = enableTunc.getCheckBox(); + settings.getView().add(enableTunc); + + tunNameItem = new TextSettingItem(UIEnv.getRsb().getString("tunname"), CONST.itemwidth, CONST.settingheight); - tunDeviceName = tunName.getTextField(); - settings.getView().add(tunName); + tunDeviceName = tunNameItem.getTextField(); + settings.getView().add(tunNameItem); + + tunWarningItem = new SettingItem(UIEnv.getRsb().getString("tundisabledwarning"), + UIEnv.getFont().deriveFont(13.0f), CONST.itemwidth, CONST.settingheight); + tunWarningItem.getLabel().setForeground(new Color(220, 80, 0)); + settings.getView().add(tunWarningItem); + + enableTun.addActionListener(e -> { + boolean en = enableTun.isSelected(); + if (en && (tunDeviceName.getText().trim().isEmpty() || tunDeviceName.getText().trim().equalsIgnoreCase("null"))) { + tunDeviceName.setText(CONST.KLALB_S_RV6); + } + updateTunVisibility(en); + }); // 链接设置标题 SettingItem six = new SettingItem(UIEnv.getRsb().getString("linksettings"), @@ -1026,6 +1048,19 @@ public class KLALBStateGUI3 extends XFrame { delayLbound.getSlider().addChangeListener(cll); } + private void updateTunVisibility(boolean enabled) { + if (tunNameItem != null) { + tunNameItem.setVisible(enabled); + } + if (tunWarningItem != null) { + tunWarningItem.setVisible(!enabled); + } + if (yspc != null && yspc.getView() != null) { + yspc.getView().revalidate(); + yspc.getView().repaint(); + } + } + // ==================== 配置保存方法 ==================== /** * 保存配置到文件 @@ -1134,11 +1169,16 @@ public class KLALBStateGUI3 extends XFrame { } } - String tunNameText=tunDeviceName.getText().trim(); - if(tunNameText.equals("") || tunNameText.equalsIgnoreCase("null")) { - kck.setTUNName(null); - }else { - kck.setTUNName(tunNameText); + // 保存TUN虚拟网卡设置 + if (!enableTun.isSelected()) { + kck.setTUNName(null); + } else { + String tunNameText = tunDeviceName.getText().trim(); + if (tunNameText.equals("") || tunNameText.equalsIgnoreCase("null")) { + kck.setTUNName(CONST.KLALB_S_RV6); + } else { + kck.setTUNName(tunNameText); + } } // 保存TCP监听设置 @@ -1539,7 +1579,10 @@ public class KLALBStateGUI3 extends XFrame { asnFieldSet.setText(vasn != null ? vasn.toString() : ""); String tunname=kck.getTUNName(); - tunDeviceName.setText(tunname!=null?tunname:""); + boolean isTunActive = (tunname != null && !tunname.trim().isEmpty() && !tunname.trim().equalsIgnoreCase("null")); + enableTun.setSelected(isTunActive); + tunDeviceName.setText(isTunActive ? tunname.trim() : ""); + updateTunVisibility(isTunActive); // 加载TCP监听 MultiProtocolSocketAddress mpat = kck.getTCPListen(); diff --git a/src/org/kne/cloud/network/klalb/ui/UIEnv.java b/src/org/kne/cloud/network/klalb/ui/UIEnv.java index eabfc6b..78a416c 100644 --- a/src/org/kne/cloud/network/klalb/ui/UIEnv.java +++ b/src/org/kne/cloud/network/klalb/ui/UIEnv.java @@ -80,7 +80,7 @@ public class UIEnv { // TODO 自动生成的 catch 块 e.printStackTrace(); }*/ - font=new Font("微软雅黑",Font.PLAIN , 12); + font = pickDefaultFont(12); /*try { font = Font.createFont(Font.PLAIN, UIEnv.class.getResourceAsStream("/assets/SourceHanSansCN-Light.otf")).deriveFont(13f); } catch (FontFormatException e1) { @@ -117,7 +117,32 @@ public class UIEnv { start.setFont(font.deriveFont(Font.BOLD, fontsize)); start.setBackground(defaultcolor); } - public static Font getFont(){ + private static Font pickDefaultFont(int size) { + String[] preferredFonts = new String[] { + "Microsoft YaHei UI", "Microsoft YaHei", "微软雅黑", + "PingFang SC", ".AppleSystemUIFont", "Helvetica Neue", + "Noto Sans CJK SC", "Source Han Sans SC", "WenQuanYi Micro Hei", + "Segoe UI", "Arial" + }; + try { + String[] available = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); + java.util.Set set = new java.util.HashSet<>(java.util.Arrays.asList(available)); + for (String name : preferredFonts) { + if (set.contains(name)) { + return new Font(name, Font.PLAIN, size); + } + } + } catch (Throwable t) { + // fallback in case of headless or security restrictions + } + Font sysFont = UIManager.getFont("Label.font"); + if (sysFont != null) { + return sysFont.deriveFont(Font.PLAIN, (float) size); + } + return new Font(Font.DIALOG, Font.PLAIN, size); + } + + public static Font getFont(){ if(icon==null) inituie(); return font;