单击隐藏显示复合材料时的swt菜单

swt menu on click hide display composites

我正在构建一个 SWT 应用程序并创建了一个菜单。菜单有多个菜单项,如添加、编辑、帮助。单击每个菜单项时,我想显示一个显示其详细信息的组合。我能够构建它,我面临的问题是,隐藏复合材料的 space 未被可见复合材料采用。怎样才能让composite占据整个space.

我还添加了选择侦听器以使当前合成可见并隐藏其他合成。在当前的应用程序中,将有多个菜单项,每个菜单项都有与之关联的组合。 Listener 需要引用所有复合材料才能使它们 visible/hidden。有没有更好的方法来做到这一点。

public class MenuToggle {

    boolean startup = true;
    Menu menu, fileMenu, helpMenu;
    Composite composite1,composite2;

    public MenuToggle(Shell shell) {
        createMenu(shell);
        createFileView(shell);
        createHelpView(shell);
        startup = false;
    }

    public void createMenu(Shell shell) {
        //Menu Bar
        menu = new Menu(shell, SWT.BAR);
        //File Menu
        fileMenu = new Menu(shell, SWT.DROP_DOWN);
        
        MenuItem fileMenuHeader = new MenuItem(menu, SWT.CASCADE);
        fileMenuHeader.setText("&File");
        fileMenuHeader.setMenu(fileMenu);

        MenuItem fileSaveItem = new MenuItem(fileMenu, SWT.PUSH);
        fileSaveItem.setText("&Save");
        
        MenuItem fileExitItem = new MenuItem(fileMenu, SWT.PUSH);
        fileExitItem.setText("E&xit");
        
        //Help Menu
        helpMenu = new Menu(shell, SWT.DROP_DOWN);
        MenuItem helpMenuHeader = new MenuItem(menu, SWT.CASCADE);
        helpMenuHeader.setText("&Help");
        helpMenuHeader.setMenu(helpMenu);

        MenuItem helpGetHelpItem = new MenuItem(helpMenu, SWT.PUSH);
        helpGetHelpItem.setText("&Get Help");
        
        shell.setMenuBar(menu);
        
        fileSaveItem.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                composite1.setVisible(true);
                ((GridData)composite1.getLayoutData()).exclude = false;
                composite2.setVisible(false);
                ((GridData)composite2.getLayoutData()).exclude = true;
                composite2.layout(true, true);
            }
        });
        helpGetHelpItem.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                composite1.setVisible(false);
                ((GridData)composite1.getLayoutData()).exclude = true;
                composite2.setVisible(true);
                ((GridData)composite2.getLayoutData()).exclude = false;
                composite2.layout(true, true);
            }
        });
    }
     
    public void createFileView(Shell shell) {
        composite1 = new Composite(shell, SWT.BORDER);
        composite1.setVisible(true);
        GridData gd1 = new GridData(SWT.FILL, SWT.FILL, true, true);
        composite1.setLayoutData(gd1);
        composite1.setLayout(new GridLayout(1,true));
        Label label = new Label(composite1, SWT.CENTER);
        label.setBounds(composite1.getClientArea());
        label.setText("Saved");
    
    }
    
    public void createHelpView(Shell shell) {
        composite2 = new Composite(shell, SWT.BORDER);
        composite2.setVisible(false);
        GridData gd2 = new GridData(SWT.FILL, SWT.FILL, true, true);
        composite2.setLayoutData(gd2);
        composite2.setLayout(new GridLayout(1,true));
        Label label1 = new Label(composite2, SWT.CENTER);
        label1.setBounds(composite2.getClientArea());
        label1.setText("No worries!");
        
    }
    
    public static void main(String[] args) {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
        shell.setText("Menu Display");
        MenuToggle instance = new MenuToggle(shell);
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }


}

这里有很多问题。

您正在为 Shell 布局使用 FillLayout,因此您在复合材料上设置的 GridData 将被忽略。您必须使用 GridLayout 作为 Shell:

  public static void main(final String[] args) {
      final Display display = new Display();
      final Shell shell = new Shell(display);
      shell.setLayout(new GridLayout());      // Changed

当您更改 exclude 设置时,您必须在复合的 parent 上调用 layout - shell:

   fileSaveItem.addSelectionListener(new SelectionAdapter() {
       @Override
       public void widgetSelected(final SelectionEvent e) {
           composite1.setVisible(true);
           ((GridData)composite1.getLayoutData()).exclude = false;
           composite2.setVisible(false);
           ((GridData)composite2.getLayoutData()).exclude = true;
           shell.layout(true, true);  // change
       }
   });
   helpGetHelpItem.addSelectionListener(new SelectionAdapter() {
       @Override
       public void widgetSelected(final SelectionEvent e) {
           composite1.setVisible(false);
           ((GridData)composite1.getLayoutData()).exclude = true;
           composite2.setVisible(true);
           ((GridData)composite2.getLayoutData()).exclude = false;
           shell.layout(true, true); // change
       }
   });

您在 Label 控件上调用 setBounds,这在您使用布局时不起作用,因为布局也会调用 setBounds 并覆盖您的设置,请使用 setLayoutData 而不是

   Label label = new Label(composite1, SWT.CENTER);
   label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));  // replace
   //label.setBounds(composite1.getClientArea());  // wrong

至于处理大量 Composite 控件,您可以调用 shell.getChildren 并循环遍历子控件。或者将复合材料添加到 List 并循环遍历它。