diff --git a/viewpanel/src/com/spineview/ObjectPanel.java b/viewpanel/src/com/spineview/ObjectPanel.java index 0d05f69..5a7ad23 100644 --- a/viewpanel/src/com/spineview/ObjectPanel.java +++ b/viewpanel/src/com/spineview/ObjectPanel.java @@ -820,12 +820,23 @@ public final class ObjectPanel { /** * 把编辑器的**滚动焦点**抢到面板的列表上(鼠标滚轮才会滚列表)。 * + * ⚠️ 2026-10-16 已停用(用户选方案 B):不再调用。原因见下面实测—— + * 它在 Stage 上找"1 个 Actor 参数 + void"的方法当 setScrollFocus,只排除了声明在 + * `dl`(Actor)/`do`(Group)/`eX`(WidgetGroup) 上的方法;可**编辑器的 Stage 类 `dt` + * 自己声明了** `D(Ldl;)V`(字节码就是 `root.addActor(actor)`,即 Stage.addActor), + * 于是它成了唯一候选被调用 → ScrollPane 被 Group.addActor 先摘下来再挂到 Stage 根, + * 坐标保留局部值 (57,824) → 整块列表(114 行)被画到**窗口左下角**, + * 被 ScrollPane 自己的裁剪框裁成 400x400 一小块(就是"列表里的 UI 跑到外面")。 + * 日志现场:`[panel] 没找到 setScrollFocus(候选 setter 1 个 / getter 0 个)`。 + * 实测焦点本来就是靠鼠标点一下列表拿到的,不需要这段。 + * * 识别方式(不猜名字、也不会误调 addActor): * - 只在 **Stage 自己声明的**方法里找(`uk`/`dt`/`lpt6` 这些层), * `addActor` 声明在 Group 上、不在这一层,所以不会被误选; * - 候选 setter = 「1 个参数是 Actor 类型、返回 void」;候选 getter = 「无参、返回 Actor 类型」; * - 调 setter 后看哪个 getter 变成了我们的面板 —— 那就是 setScrollFocus 那一对,日志会写出来。 */ + @SuppressWarnings("unused") static void grabScrollFocus(final State state) { try { Object stage = SceneObjects.global(state.loader, "uk"); @@ -1376,8 +1387,11 @@ public final class ObjectPanel { } try { ((Runnable) route[1]).run(); - Object st = LAST_STATE; - if (st instanceof State) grabScrollFocus((State) st); + // 这里以前会调 grabScrollFocus(state) 去抢滚动焦点。 + // 2026-10-16 停用:它会把列表的 ScrollPane 当成 Stage.addActor 的参数传进去, + // 结果 ScrollPane 被搬出面板、挂到 Stage 根,列表就画到窗口左下角去了 + // (证据:dt.D(Ldl;)V 的字节码 = root.addActor;探针实测 root 子控件只剩 2 个)。 + // 滚动焦点本来就靠鼠标点一下列表拿到,不需要这段。 } catch (Throwable error) { System.err.println("[panel] 动作失败: " + error); error.printStackTrace(System.err);