Прежде чем мы начнем создавать скины для Аккордеона, мы должны сначала решить, какой внешний вид мы хотим достичь. После долгих поисков я наткнулся на привлекательный аккордеон asp.net, который я бы сделал идеальным предметом для этого урока. Из этого туториала вы узнаете, как взять аккордеон по умолчанию и сделать из него скин, похожий на аккордеон asp.net.
Сравнивая аккордеон asp.net со стандартным JSCAccordion, можно было бы предположить, что для преобразования потребуется много кода, однако на самом деле это не так.
При создании скина для Аккордеона у нас есть несколько вариантов, некоторые из которых включают расширение существующего Аккордеона, расширение существующего AccordionUI или, наконец, простую настройку настроек аккордеона в коде. Я буду следовать последнему подходу, так как считаю, что это приведет к более простой демонстрации, но все варианты действительны.
Шаг 1: Создайте экземпляр JSCAccordion
Первый шаг в нашем руководстве включает создание нового JSCAccordion и добавление необходимых вкладок «Почта», «Заметки» и «Контакты».
JSCAccordion accordion = new JSCAccordion(); accordion.addTab("Mail", new JLabel()); accordion.addTab("Notes", new JLabel()); accordion.addTab("Contacts", new JLabel());
Хотя можно добавить любой компонент на вкладку аккордеона, мы добавим JLabel, так как он естественным образом прозрачен (не непрозрачен) и позволит нам легко видеть фон вкладки.
Шаг 2: Отрегулируйте основные настройки на JSCAccordion
Для того, чтобы мы достигли компоновки аккордеона asp.net, нам нужно будет изменить несколько основных настроек в Аккордеоне.
-
Нам нужно изменить ориентацию аккордеона, чтобы визуализировать вертикально.
-
Высота вкладки должна быть установлена на 31 пикселей.
-
Нам нужно отключить рендеринг теней аккордеона.
-
Аккордеон asp.net имеет границу, состоящую из черного, а затем белого прямоугольника.
//lays out the accordion's tabs to move vertically. accordion.setTabOrientation(TabOrientation.VERTICAL); //adjusts the height of the tabs to be 31 pixels accordion.setTabHeight(31); //stops the accordion rendering its shadows accordion.setDrawShadow(false); //the asp.net accordion is framed with a black then white border accordion.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(Color.BLACK), BorderFactory.createLineBorder(Color.WHITE)) );
Шаг 3: Настройка параметров в SteelAccordionUI
На предыдущем шаге мы изменили настройки, найденные на JSCAccordion, однако для достижения окончательного вида нам нужно будет настроить некоторые параметры в пользовательском интерфейсе Accordion. Пользовательским интерфейсом по умолчанию для Accordion является SteelAccordionUI, и именно этим пользовательским интерфейсом мы теперь будем манипулировать.
Чтобы приблизить нас на один шаг к аккордеону asp.net, теперь мы установим все отступы на SteelAccordionUI на ноль.
//we know the default UI for the accordion is the SteelAccordionUI //so we cast the UI to a SteelAccordionUI. SteelAccordionUI steelAccordionUI = (SteelAccordionUI) accordion.getUI(); //we set all the paddings to zero steelAccordionUI.setHorizontalBackgroundPadding(0); steelAccordionUI.setVerticalBackgroundPadding(0); steelAccordionUI.setHorizontalTabPadding(0); steelAccordionUI.setVerticalTabPadding(0); steelAccordionUI.setTabPadding(0)
Установка всех отступов в ноль дает нам следующий результат.
Шаг 4: Замените фоновый художник
Все компоненты из Java Swing Components используют художников для создания своего внешнего вида. Painter — это простой класс, содержащий логику для рисования (рисования) компонента. Преимущество сохранения этой логики в художнике состоит из двух частей: во-первых, легко писать новых художников, а во-вторых, все художники взаимозаменяемы. Конечным результатом этого является то, что становится очень легко изменить внешний вид компонента.
Среда, на которой основаны все компоненты Java Swing Components, включает несколько простых предварительно оптимизированных художников. Вместо того, чтобы создавать нового художника с нуля, я просто буду использовать существующих художников.
Взглянув на аккордеон asp.net, мы видим, что нам нужно нарисовать градиент от белого до серого по горизонтали, чтобы сформировать фон. Для этого мы будем использовать GradientColorPainter. Этот художник рисует простой градиент, начиная с startColor и заканчивая endColor в указанном направлении.
//we will replace the current background painter with a new //GradientColorPainter. GradientColorPainter backgroundPainter = new GradientColorPainter(); //paint gradient horizontally backgroundPainter.setGradientDirection(GradientDirection.HORIZONTAL); //start with white backgroundPainter.setStartColor(new Color(255,255,255)); //end with grey backgroundPainter.setEndColor(new Color(214,213,228)); //apply the painter to the accordion accordion.setBackgroundPainter(backgroundPainter);
Результат применения нового фонового художника дает следующий результат.
Шаг 5: Создайте новый AccordionTabRenderer
Последний шаг в нашем процессе создания скинов — это создание совершенно нового AccordionTabRenderer. AccordionTabRenderer — это интерфейс, используемый аккордеоном для «штамповки» отдельного компонента для каждой вкладки. Он работает точно так же, как TableCellRenderers на стандартном Jtable.
Интерфейс AccordionTabRenderer имеет единственный метод getTabComponent.
public JComponent getTabComponent(GetTabComponentParameter parameters);
JComponent, возвращаемый этим методом, будет использоваться для рисования вкладок аккордеона. AccordionTabRenderer отвечает за чтение информации из аргумента параметров и возврат соответствующим образом настроенного компонента. Преимущество использования средства визуализации состоит в том, что он экономит память, используя только один компонент для всех вкладок, а также позволяет разработчику возвращать любой компонент, который они хотят. Единственное, что нужно помнить, это то, что возвращаемый компонент нарисован на экране и не добавлен в аккордеон как обычный компонент. Для всех интенсивных целей он используется в качестве резинового штампа.
Самым простым компонентом, который нужно вернуть для этого урока, была бы метка, так как в ней есть текст и изображение, и это именно то, что нам нужно. Мы создадим класс с именем DemoAccordionTabRenderer, который реализует AccordionTabRenderer и расширяет JLabel. Каждый раз, когда вызывается метод getTabComponent, он возвращает сам себя.
В конструкторе нашего класса мы загрузим три изображения, необходимые для рендерера. Эти изображения извлекаются в конструкторе, а не во время метода getTabComponent, так как это будет приводить к io каждый раз, когда отображается вкладка. К сожалению, у меня не было доступа к иконкам, используемым в аккордеоне asp.net, поэтому я буду использовать некоторые отличные иконки из библиотеки иконок Tango .
private ImageIcon mailImage; private ImageIcon notesImage; private ImageIcon contactsImage; public DemoAccordionTabRenderer() { try { //images are loaded in the constructor to improve performance. //loading images in the getTabComponent method will result in the images //being loaded every time a tab is drawn. mailImage = new ImageIcon(ImageIO.read(Thread.currentThread() .getContextClassLoader().getResourceAsStream("mail.png"))); notesImage = new ImageIcon(ImageIO.read(Thread.currentThread(). getContextClassLoader().getResourceAsStream("notes.png"))); contactsImage = new ImageIcon(ImageIO.read(Thread.currentThread(). getContextClassLoader().getResourceAsStream("contacts.png"))); } catch (IOException e) { e.printStackTrace(); } }
Теперь о самом важном методе — методе getTabComponent. В этом методе мы будем читать информацию из аргумента параметров и настраивать наш рендерер.
@Override public JComponent getTabComponent(GetTabComponentParameter parameters) { //read the tabText from the parameter setText(parameters.tabText); //set the text color to white setForeground(Color.WHITE); //use a slightly smaller bold font setFont(getFont().deriveFont(Font.BOLD, 11f)); //create a border to help align the label setBorder(BorderFactory.createEmptyBorder(0,8,0,0)); //set the gap between the icon and the text to 8 pixels setIconTextGap(8); //set the appropriate image based on the tabText. if ("Mail".equals(parameters.tabText)) { setIcon(mailImage); } if ("Notes".equals(parameters.tabText)) { setIcon(notesImage); } if ("Contacts".equals(parameters.tabText)) { setIcon(contactsImage); } //returns itself, which extends JLabel return this; }
Последний шаг, необходимый для создания внешнего вида аккордеона asp.net, — нарисовать соответствующий фон для AccordionTabRenderer. Это может быть достигнуто несколькими способами, самым простым из которых является простое переопределение метода paintComponent в AccordionTabRenderer.
Фон вкладок аккордеона asp.net представляет собой сложный линейный градиент, состоящий из нескольких цветов. Чтобы добиться такого же внешнего вида, я буду использовать LinearGradientColorPainter из инфраструктуры Java Swing Components. Этот художник рисует вместе несколько градиентов на основе предоставленного набора цветов и плавающих элементов. Работа художника выходит за рамки данного руководства, однако дополнительную информацию можно найти в api javadocs Sun (Oracle) LinearGradientPaint .
В методе paintComponent мы закрасим фон вкладки с помощью нашего LinearGradientColorPainter, а затем просто вызовем super.paintComponent (), чтобы нарисовать стандартный JLabel поверх фона.
private LinearGradientColorPainter painter = new LinearGradientColorPainter(); @Override protected void paintComponent(Graphics g) { //setup the painter fractions painter.setColorFractions(new float[]{ 0.0f, 0.49f, 0.5f, 0.51f, 0.8f, 1.0f}); //setup the painter colors painter.setColors(new Color[]{ new Color(167,163,189),new Color(143,138,169), new Color(131,126,160),new Color(116,110,146), new Color(119,113,148), new Color(138,133,164)}); //paint the background painter.paint((Graphics2D) g, new Rectangle(0, 0, getWidth(), getHeight())); //original color on g is stored and then later reset //this is to prevent clobbering of the Graphics object. Color originalColor = g.getColor(); //paints a simple line on the bottom of the tab g.setColor(new Color(87,86,111)); g.drawLine(0, getHeight()-1, getWidth(), getHeight()-1); g.setColor(originalColor); //draws the label on top of the background we just painted. super.paintComponent(g); }
Последний шаг — назначить наш пользовательский AccordionTabRenderer на аккордеон.
//apply the new TabRenderer to the accordion. accordion.setVerticalAccordionTabRenderer(new DemoAccordionTabRenderer());
Окончательный результат всей нашей тяжелой работы можно увидеть на изображении ниже.
Хотя может показаться, что кода много, увидеть весь код вместе действительно показывает, насколько прост процесс создания скинов.
JSCAccordion accordion = new JSCAccordion(); accordion.addTab("Mail", new JLabel()); accordion.addTab("Notes", new JLabel()); accordion.addTab("Contacts", new JLabel()); //lays out the accordion's tabs to move vertically. accordion.setTabOrientation(TabOrientation.VERTICAL); //adjusts the height of the tabs to be 31 pixels accordion.setTabHeight(31); //stops the accordion rendering its shadows accordion.setDrawShadow(false); //the asp.net accordion has a border comprising a black then white border accordion.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.BLACK),BorderFactory.createLineBorder(Color.WHITE))); //we know the default UI for the accordion is the SteelAccordionUI SteelAccordionUI steelAccordionUI = (SteelAccordionUI) accordion.getUI(); //we set all the paddings to zero steelAccordionUI.setHorizontalBackgroundPadding(0); steelAccordionUI.setVerticalBackgroundPadding(0); steelAccordionUI.setHorizontalTabPadding(0); steelAccordionUI.setVerticalTabPadding(0); steelAccordionUI.setTabPadding(0); //we will replace the current background painter with a new //GradientColorPainter. GradientColorPainter backgroundPainter = new GradientColorPainter(); //paint gradient horizontally backgroundPainter.setGradientDirection(GradientDirection.HORIZONTAL); //start with white backgroundPainter.setStartColor(new Color(255,255,255)); //end with grey backgroundPainter.setEndColor(new Color(214,213,228)); //apply the painter to the accordion accordion.setBackgroundPainter(backgroundPainter); //apply the new TabRenderer to the accordion. accordion.setVerticalAccordionTabRenderer(new DemoAccordionTabRenderer());
Это подводит нас к концу урока, для тех из вас, кто прошел этот этап, к этой статье прилагается финальный демонстрационный файл и исходный код. наслаждаться