Статьи

Аккордеонная панель инструментов JavaFX для платформы NetBeans

В предыдущем руководстве по интеграции JavaFX с платформой NetBeans мы показали, как заменить NetBeans Swing MenuBar элементом управления типа Accordion JavaFX, который мы назвали AccordionMenu.   Затем это JavaFX AccordionMenu было добавлено в TopComponent SlideIn платформы NetBeans. Это высвободило значение вертикального пространства, а также обеспечило интерфейс ButtonMenu, который был более удобным для сенсорных дисплеев. Когда это меню не используется, оно автоматически вставляется и сворачивается. 

Вы можете найти это руководство здесь:  http://netbeans.dzone.com/articles/javafx-accordion-slide-out

Это отлично подходит для дисплеев Kiosk или систем HUD, которые могут нуждаться только во взаимодействии в отдельных случаях, или, возможно, для наземной системы NASA, для   которой требуется большая 3D-визуализация. Но как насчет панелей инструментов? В предыдущем уроке мы просто скрывали их, чтобы максимизировать вертикальное пространство. Итак, теперь давайте расширим концепцию Accordion для панелей инструментов. Это просто!

И снова JavaFX является частью решения, поскольку он предоставляет некоторые возможности, которых нет у базовых компонентов Swing, доступных в платформе NetBeans. Чтобы полностью понять и следовать этому уроку, вам нужно начать с предыдущего урока, упомянутого выше. Как указано в этой статье, и снова здесь оба эти учебника развиваются по следующим ссылкам:

http://netbeans.dzone.com/articles/how-integrate-javafx-netbeans

http://netbeans.dzone.com/articles/how-integrate-javafx-netbeans-part2

Эти статьи были написаны Geertjan Wielenga,   и станет ясно, что большая часть базового кода для выполнения этой статьи была расширена на примере Geertjan. На самом деле … лучший термин был бы «явно скопирован», но давайте не будем спорить о семантике. Еще раз спасибо Гертьян!

Статьи, похожие на это, которые могут быть полезны, находятся ниже

http://netbeans.dzone.com/articles/javafx-fxml-meets-netbeans  

http://netbeans.dzone.com/articles/how-embed-javafx-chart-visual

http://netbeans.dzone.com/articles/how-integrate-javafx-netbeans-part3

http://netbeans.dzone.com/articles/how-integrate-javafx-netbeans-part4

http: //netbeans.dzone. com / article / how-integrate-javafx-netbeans-part5

Все эти статьи слабо связаны между собой в уроке, посвященном объяснению и демонстрации преимуществ интеграции JavaFX в платформу NetBeans. 

Мы начнем здесь, предполагая, что вы прошли предыдущий урок, который заменяет MenuBar.

Шаг 1. Скройте панели инструментов по умолчанию: 

import org.openide.modules.ModuleInstall;

public class Installer extends ModuleInstall {

    @Override
    public void restored() {
            System.setProperty("netbeans.winsys.no_toolbars", "true");
    }
}

Шаг 2. Создайте «AccordionToolbar» с помощью JavaFX.

Мы будем использовать шаблон, аналогичный AccordionMenu из предыдущего урока, за исключением гораздо более простого. Фактически мы можем полностью использовать методы buildToolBarStructure () и getInputStream () из учебного пособия по инструментальной панели Geertjan. Однако нам нужно иметь собственный рабочий процесс createScene (), который больше похож на упрощенную версию AccordionMenu. Основной алгоритм таков:


Создайте компонент, расширяющий JFXPanel. Реализуйте

стандартный шаблон Platform.runLater () для создания
цикла сцены JavaFX
через каждый объект файла верхнего уровня в папке «Панели инструментов» файловой системы приложения:


Создайте JavaFX TitledPane для каждого файлового объекта.

Создайте JavaFX ToolBar для каждого TitledPane.

Добавьте элементы ButtonMenu со значками и действиями

на панель
инструментов. Добавьте ToolBar в TitledPane.
Добавьте TitledPane в компонент JavaBX VBox.

Добавьте VBox на сцену

Компонент JavaFX ToolBar служит заменой 1: 1 для панели инструментов Swing в этом контексте, поэтому здесь нет ничего нового. Однако комбинация JavaFX VBox / TitledPane обеспечивает некоторые новые функциональные возможности благодаря компактному разборному виду с небольшой анимацией. В предыдущем уроке использовалась панель «Аккордеон», но аккордеоны анимированы так, что в данный момент можно увидеть только один сегмент. Комбинация VBox / TitledPane позволяет при желании держать открытыми несколько сегментов, что больше соответствует поведению панелей инструментов.

Ниже приведен код моего класса AccordionToolbar. Вы увидите, где я много позаимствовал из примера Гиртджана и предыдущего учебника AccordionMenu:

import java.awt.image.RenderedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TitledPane;
import javafx.scene.control.ToolBar;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javax.imageio.ImageIO;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.SwingUtilities;
import org.openide.awt.Actions;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.Exceptions;
import org.openide.util.ImageUtilities;

/**
 *
 * @author SPhillips (King of Australia)
 */
public class AccordionToolbar extends JFXPanel{
    
    public VBox vBoxPane;
    public String transparentCSS = "-fx-background-color: rgba(0,100,100,0.1);";
    
    public AccordionToolbar() {
        super();
        this.setBorder(null);        
        // create JavaFX scene
        Platform.setImplicitExit(false);
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                createScene(); //Standard Swing Interop Pattern
            }
        });        
    }
    private void createScene() {
        FileObject toolbarsFolder = FileUtil.getConfigFile("Toolbars");
        FileObject[] toolbarKids = toolbarsFolder.getChildren();
        //for each toolbar folder need to create a TilePane and add it to an Accordion
        List<TitledPane> titledPaneList = new ArrayList<>();
        for (FileObject toolbarKid : FileUtil.getOrder(Arrays.asList(toolbarKids), true)) {
            ToolBar newToolbarFromFileObject = new ToolBar();
            //Blatently ripped off from Geertjan's example, similar to the MenuBar example
            try {
                buildToolBarStructure(toolbarKid, newToolbarFromFileObject);
            } catch (FileNotFoundException ex) {
                Exceptions.printStackTrace(ex);
            }            
            //The new toolbar can be added directly to the TitledPane
            TitledPane newTitledPaneFromFileObject = new TitledPane(toolbarKid.getName(), newToolbarFromFileObject );
            newTitledPaneFromFileObject.setAnimated(true);
            newTitledPaneFromFileObject.setStyle(transparentCSS);
            titledPaneList.add(newTitledPaneFromFileObject);
        }
        Group g = new Group();
        Scene scene = new Scene(g, 400, 400,new Color(0.0,0.0,0.0,0.0));
        scene.setFill(null);
        g.setStyle(transparentCSS);
        //Instead of an Accordion... a custom VBox allows us to leave sections expanded 
        vBoxPane = new VBox();
        vBoxPane.setStyle(transparentCSS);
        vBoxPane.setFillWidth(true);
        vBoxPane.getChildren().addAll(titledPaneList);
        g.getChildren().add(vBoxPane);
        setScene(scene);
        
        validate();
        this.setOpaque(true);
        this.setBackground(new java.awt.Color(0.0f, 0.0f, 0.0f, 0.0f));
    }
    
    private static void buildToolBarStructure(FileObject oneMainToolBarKid, ToolBar newToolbarFromFileObject) throws FileNotFoundException {
        for (FileObject oneSecondLevelToolBarKid : oneMainToolBarKid.getChildren()) {
            final Action instanceObj =
                    FileUtil.getConfigObject(
                    oneSecondLevelToolBarKid.getPath(),
                    Action.class);
            //Name stuff:
            String name = (String) instanceObj.getValue(Action.NAME);
            String cutAmpersand = Actions.cutAmpersand(name);
            //Icon stuff:
            Icon icon = (Icon) instanceObj.getValue(Action.SMALL_ICON);
            ImageView iv = new ImageView();
            //Optionally, include the name in the button:
            //Button toolbarButton = new Button(cutAmpersand);
            Button toolbarButton = new Button();
            if (icon != null) {
                java.awt.Image awtImage = ImageUtilities.icon2Image(icon);
                Image image = new Image(getInputStream(awtImage));
                iv.setImage(image);
                toolbarButton.setGraphic(iv);
            }
            toolbarButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(final ActionEvent t) {
                    try {
                        SwingUtilities.invokeAndWait(new Runnable() {
                            @Override
                            public void run() {
                                java.awt.event.ActionEvent event =
                                        new java.awt.event.ActionEvent(
                                        t.getSource(),
                                        t.hashCode(),
                                        t.toString());
                                instanceObj.actionPerformed(event);
                            }
                        });
                    } catch (InterruptedException ex) {
                        Exceptions.printStackTrace(ex);
                    } catch (InvocationTargetException ex) {
                        Exceptions.printStackTrace(ex);
                    }
                }
            });
            newToolbarFromFileObject.getItems().add(toolbarButton);
        }
    }    
    private static InputStream getInputStream(java.awt.Image image) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        InputStream fis = null;
        try {
            ImageIO.write((RenderedImage) image, "png", os);
            fis = new ByteArrayInputStream(os.toByteArray());
        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        }
        return fis;
    }    
}

Шаг 3. Создайте слайд в TopComponent для нового AccordionToolbar.

Как и в учебном курсе AccordionMenu, теперь вы можете добавить свой компонент AccordionToolbar в слайд TopComponent. Теперь, когда у вас есть компонент JFXPanel Swing Interop, ваш TopComponent платформы NetBeans не должен знать о JavaFX. Воспользуйтесь мастером окон и выберите «Скольжение влево» в качестве режима. Я бы также посоветовал сделать этот компонент закрытым, иначе пользователь может потерять возможность использовать панель инструментов. Вот аннотации и код конструктора в моем TopComponent:

@ConvertAsProperties(
        dtd = "-//javafxwizard.jfxtool//SlidingAccordionToolbar//EN",
        autostore = false)
@TopComponent.Description(
        preferredID = "SlidingAccordionToolbarTopComponent",
        //iconBase="SET/PATH/TO/ICON/HERE", 
        persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "leftSlidingSide", openAtStartup = true)
@ActionID(category = "Window", id = "javafxwizard.jfxtool.SlidingAccordionToolbarTopComponent")
@ActionReference(path = "Menu/JavaFX" /*, position = 333 */)
@TopComponent.OpenActionRegistration(
        displayName = "#CTL_SlidingAccordionToolbarAction",
        preferredID = "SlidingAccordionToolbarTopComponent")
@Messages({
    "CTL_SlidingAccordionToolbarAction=SlidingAccordionToolbar",
    "CTL_SlidingAccordionToolbarTopComponent=Accordion Toolbar",
    "HINT_SlidingAccordionToolbarTopComponent=A Sliding Accordion Toolbar"
})
public final class SlidingAccordionToolbarTopComponent extends TopComponent {

    public AccordionToolbar accordionToolbar;
    
    public SlidingAccordionToolbarTopComponent() {
        initComponents();
        setName(Bundle.CTL_SlidingAccordionToolbarTopComponent());
        setToolTipText(Bundle.HINT_SlidingAccordionToolbarTopComponent());
        putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
        putClientProperty(TopComponent.PROP_UNDOCKING_DISABLED, Boolean.TRUE);
        putClientProperty(TopComponent.PROP_KEEP_PREFERRED_SIZE_WHEN_SLIDED_IN, Boolean.TRUE);
        setLayout(new BorderLayout());
        //Standard JFXPanel Swing Interop Pattern
        accordionToolbar = new AccordionToolbar();
        //transparency
        Color transparent = new Color(0.0f, 0.0f, 0.0f, 0.0f);
        accordionToolbar.setOpaque(true);
        accordionToolbar.setBackground(transparent);
        this.add(accordionToolbar);
        this.setOpaque(true);
        this.setBackground(transparent);
        this.setBorder(null);
    }

Шаг 4. Посмотрите, как это здорово выглядит

Теперь у нас есть выдвижная панель инструментов приложения, предоставляемая компонентами JavaFX. Эти компоненты могут быть «оформлены» с помощью стилей CSS, и поэтому меню может быть создано по-разному для разных приложений. Новый AccordionToolbar был разработан таким образом, чтобы несколько панелей инструментов могли отображаться одновременно или не отображаться вообще.

В сочетании с AccordionMenu вы получите красивый слайд в рабочей области на основе и должен выглядеть примерно так: