代码之家  ›  专栏  ›  技术社区  ›  LuminousNutria

尝试在我的控制器中使用窗格的原始版本和全屏版本也会更改窗口版本中的窗格

  •  0
  • LuminousNutria  · 技术社区  · 6 年前

    我有一个ScreenController类,它允许在JavaFX程序中轻松切换根窗格。它使用HashMap来实现这一点,HashMap使用字符串键存储窗格值。

    但是,每当我现在切换屏幕时,总是使用窗格的全屏版本。

    好像 goFullscreen() 我用来创建全屏窗格版本的方法正在修改这两个版本,即使Java是通过值传递的。

    如何在ScreenController类windowedRootMap中获取HashMap属性,并在不进行全屏缩放的情况下返回原始窗格?

    /**
     * Creates an appropriately scaled fullscreen version of the argument Pane object.
     * 
     * @param contentPane The Pane to create a fullscreen version of.
     * @return Pane
     */
    private static Pane goFullscreen(Pane contentPane) {
    
       // get original dimensions and their ratio.
       final double windowedWidth = 1280.0;
       final double windowedHeight = 800.0;
       final double windowedRatio = windowedWidth / windowedHeight;
    
       // get fullscreen width and height from monitor dimensions
       final double fullscreenWidth = Screen.getPrimary().getBounds().getWidth();
       final double fullscreenHeight = Screen.getPrimary().getBounds().getHeight();
    
       // find how much to scale by
       double scaleFactor;
       if (fullscreenWidth / fullscreenHeight > windowedRatio)
          scaleFactor = fullscreenHeight / windowedHeight;
       else
          scaleFactor = fullscreenWidth / windowedWidth;
    
       // scale the contents of the Pane appropriately
       Scale scale = new Scale(scaleFactor, scaleFactor);
       contentPane.getTransforms().setAll(scale);
       contentPane.setPrefWidth(fullscreenWidth / scaleFactor);
       contentPane.setPrefWidth(fullscreenHeight / scaleFactor);
    
       return contentPane;
    }
    
    /**
     * Allows switching root nodes easily.
     */
    private class ScreenController {
    
       private HashMap<String, Pane> windowedRootMap = new HashMap<>();
       private HashMap<String, Pane> fullscreenRootMap = new HashMap<>();
       private Scene currentScene;
    
       private ScreenController(Scene currentScene) {
    
          this.currentScene = currentScene;
       }
    
       private void addScreen(String name, Pane pane) {
    
          this.windowedRootMap.put(name, pane);
          this.fullscreenRootMap.put(name, goFullscreen(pane));
       }
    
       private void activate(String name) {
    
          this.currentScene.setRoot(this.windowedRootMap.get(name));
       }
    }
    
    0 回复  |  直到 6 年前
        1
  •  2
  •   Slaw    6 年前

    你说的对,Java是 传递值 实例 . 下面的问题有许多很好的答案,可以更详细地解释这一点:

    假设你不想保持两个不同的 Pane 例如,一个选项是根据所处的模式简单地设置属性。我不太确定您希望您的代码最终是什么样子,但它可能看起来像:

    import java.util.Map;
    import java.util.HashMap;
    import javafx.geometry.Dimension2D;
    import javafx.scene.Scene;
    import javafx.scene.layout.Pane;
    import javafx.scene.transform.Scale;
    
    public class ScreenController {
    
        private final Map<String, Foo> map = new HashMap<>();
        private final Scene scene;
    
        public ScreenController(Scene scene) {
            this.scene = scene;
        }
    
        public void register(String name, Pane pane) {
            map.put(name, pane);
        }
    
        public void activate(String name) {
            scene.setRoot(map.get(name).pane);
        }
    
        private static class Foo {
    
            private final Pane pane;
            private final Dimension2D normalSize;
            private final Dimension2D fullScreenSize;
            private final Scale scale;
    
            private Foo(Pane pane) {
                this.pane = pane;
                // set the other fields...
            }
    
            private void enterFullScreenMode() {
                 pane.setPrefSize(fullScreenSize.getWidth(), fullScreenSize.getHeight());
                 pane.getTransforms().add(scale);
            }
    
            private void exitFullScreenMode() {
                 pane.setPrefSize(normalSize.getWidth(), normalSize.getHeight());
                 pane.getTransforms().remove(scale);
            }
    
        }
    
    }
    

    但是,请记住 Scene 大小与场景图中的“常规”节点不同。设置首选大小可能没有效果。从 documentation .

    Node 通过设置 root Group 作为根,场景图的内容将被场景的宽度和高度剪裁,并且对场景大小的更改(如果用户调整舞台大小)不会改变场景图的布局。如果一个可调整大小的节点(布局 Region Control )设置为根,则根的大小将跟踪场景的大小,从而使内容根据需要中继出去。


    enum 作为 Map ,而不是 String . 还可以看看 java.util.EnumMap .