/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ro.nextreports.designer.chart; import ro.nextreports.engine.chart.ChartRunner; import ro.nextreports.engine.chart.ChartType; import ro.nextreports.engine.chart.Chart; import ro.nextreports.engine.chart.ChartTitle; import ro.nextreports.engine.util.NameType; import ro.nextreports.engine.exporter.util.function.GFunction; import ro.nextreports.engine.exporter.util.function.FunctionFactory; import com.jgoodies.looks.Options; import com.jgoodies.looks.HeaderStyle; import javax.swing.*; import javax.swing.plaf.basic.BasicComboBoxRenderer; import ro.nextreports.designer.FunctionRenderer; import ro.nextreports.designer.Globals; import ro.nextreports.designer.action.chart.PreviewChartAction; import ro.nextreports.designer.datasource.DataSource; import ro.nextreports.designer.datasource.DefaultDataSourceManager; import ro.nextreports.designer.querybuilder.RuntimeParametersPanel; import ro.nextreports.designer.template.chart.action.ApplyTemplateAction; import ro.nextreports.designer.template.chart.action.ExtractTemplateAction; import ro.nextreports.designer.ui.MagicButton; import ro.nextreports.designer.util.DropDownListButton; import ro.nextreports.designer.util.I18NSupport; import ro.nextreports.designer.util.ImageUtil; import ro.nextreports.designer.util.Show; import ro.nextreports.designer.util.SwingUtil; import java.awt.*; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.ItemListener; import java.awt.event.ItemEvent; import java.util.List; import java.util.ArrayList; /** * User: mihai.panaitescu * Date: 16-Dec-2009 * Time: 10:39:17 */ public class ChartLayoutPanel extends JPanel { private JLabel functionLabel; private JLabel yLabel; private JLabel xLabel; private DropDownListButton xButton; private DropDownListButton yButton; private JButton titleButton; private JButton mainButton; private int titleAlignment = GridBagConstraints.CENTER; private JPanel panel; private JComboBox functionComboBox; private List<NameType> columns; private JComboBox dataSourcesComboBox; private Dimension columnDim = new Dimension(150, 20); private Dimension titleDim = new Dimension(310, 30); private Dimension mainDim = new Dimension(310, 260); private Dimension comboDim = new Dimension(100, 20); private PreviewChartAction previewFlashAction = new PreviewChartAction(ChartRunner.GRAPHIC_FORMAT, ChartRunner.FLASH_TYPE); private PreviewChartAction previewHTML5Action = new PreviewChartAction(ChartRunner.GRAPHIC_FORMAT, ChartRunner.HTML5_TYPE); private PreviewChartAction previewImageAction = new PreviewChartAction(ChartRunner.IMAGE_FORMAT, ChartRunner.NO_TYPE); private ApplyTemplateAction applyTemplateAction = new ApplyTemplateAction(); private ExtractTemplateAction extractTemplateAction = new ExtractTemplateAction(); public ChartLayoutPanel() { init(); } private void init() { setLayout(new GridBagLayout()); panel = new JPanel(); panel.setLayout(new GridBagLayout()); panel.setBorder(UIManager.getBorder("TableHeader.cellBorder")); functionLabel = new JLabel("<html><b>" + I18NSupport.getString("function.title") + "</b></html>"); List<GFunction> functions = FunctionFactory.getFunctions(); DefaultComboBoxModel functionComboModel = new DefaultComboBoxModel(functions.toArray()); functionComboBox = new JComboBox(functionComboModel); functionComboBox.setRenderer(new FunctionRenderer()); functionComboBox.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { String function = ((GFunction) e.getItem()).getName(); Globals.getChartDesignerPanel().getChart().setYFunction(function); } }); yLabel = new JLabel("<html><b>" + I18NSupport.getString("chart.ycolumn") + "</b></html>"); yButton = new DropDownListButton(I18NSupport.getString("chart.column.select")) { protected String getText(String item) { return getShownText(item); } protected void afterSelection(String item, Boolean marked) { List<String> yColumns = Globals.getChartDesignerPanel().getChart().getYColumns(); if (yColumns == null) { yColumns = new ArrayList<String>(); } if (yColumns.size() == 0) { yColumns.add(item); } else { yColumns.set(0, item); } Globals.getChartDesignerPanel().getChart().setYColumns(yColumns); Globals.getChartDesignerPanel().getPropertiesPanel().updateYColumnProperty(item); updateFunctions(marked); } }; yButton.setHorizontalAlignment(SwingConstants.RIGHT); yButton.setArrowTooltip(I18NSupport.getString("chart.column.y.tooltip")); yButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Globals.getChartDesignerPanel().selectProperties(ChartPropertyPanel.YCOLUMN_CATEGORY); } }); setFixedDimension(yButton, columnDim); xLabel = new JLabel("<html><b>" + I18NSupport.getString("chart.xcolumn") + "</b></html>"); xButton = new DropDownListButton(I18NSupport.getString("chart.column.select")) { protected String getText(String item) { return getShownText(item); } protected void afterSelection(String item, Boolean marked) { Globals.getChartDesignerPanel().getChart().setXColumn(item); Globals.getChartDesignerPanel().getPropertiesPanel().updateXColumnProperty(item); } }; xButton.setHorizontalAlignment(SwingConstants.RIGHT); xButton.setArrowTooltip(I18NSupport.getString("chart.column.x.tooltip")); xButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Globals.getChartDesignerPanel().selectProperties(ChartPropertyPanel.XCOLUMN_CATEGORY); } }); setFixedDimension(xButton, columnDim); titleButton = new MagicButton(I18NSupport.getString("chart.title")); setFixedDimension(titleButton, titleDim); titleButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Globals.getChartDesignerPanel().selectProperties(ChartPropertyPanel.TITLE_CATEGORY); } }); mainButton = new MagicButton(); setFixedDimension(mainButton, mainDim); mainButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Globals.getChartDesignerPanel().selectProperties(ChartPropertyPanel.MAIN_CATEGORY); } }); mainButton.setSelected(true); panel.add(titleButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, titleAlignment, GridBagConstraints.NONE, new Insets(10, 10, 5, 10), 0, 0)); panel.add(functionLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 10, 0, 0), 0, 0)); panel.add(functionComboBox, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 10, 0, 0), 0, 0)); panel.add(yLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 10, 0, 0), 0, 0)); panel.add(yButton.getPanel(), new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 10, 0, 0), 0, 0)); panel.add(mainButton, new GridBagConstraints(1, 3, 1, 3, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(5, 10, 5, 10), 0, 0)); panel.add(xLabel, new GridBagConstraints(1, 8, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 10, 5, 10), 0, 0)); panel.add(xButton.getPanel(), new GridBagConstraints(1, 9, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 10, 5, 10), 0, 0)); panel.add(new JLabel(), new GridBagConstraints(0, 10, 1, 1, 0.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.VERTICAL, new Insets(0, 0, 0, 0), 0, 0)); panel.add(new JLabel(), new GridBagConstraints(2, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); add(createToolBar(), new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 2), 0, 0)); JScrollPane scr = new JScrollPane(panel); add(scr, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); } private void updateFunctions(Boolean marked) { List<GFunction> functions; if (marked) { // not-number column (only count functions) functions = FunctionFactory.getCountFunctions(); } else { functions = FunctionFactory.getFunctions(); } DefaultComboBoxModel functionComboModel = new DefaultComboBoxModel(functions.toArray()); functionComboBox.setModel(functionComboModel); boolean set = setYFunction(Globals.getChartDesignerPanel().getChart().getYFunction()); if (!set) { Globals.getChartDesignerPanel().getChart().setYFunction(functions.get(0).getName()); } } private void setFixedDimension(JComponent component, Dimension dim) { component.setPreferredSize(dim); component.setMinimumSize(dim); component.setMaximumSize(dim); } public void setChart(Chart chart) { previewFlashAction.setChart(chart); previewHTML5Action.setChart(chart); previewImageAction.setChart(chart); setTitle(chart.getTitle().getTitle()); setTitleFont(chart.getTitle().getFont()); setTitleColor(chart.getTitle().getColor()); setTitleAlignment(chart.getTitle().getAlignment()); setMainBackground(chart.getBackground()); if (chart.getType() != null) { setType(chart.getType().getType()); } String xColumn = chart.getXColumn(); setXColumn(xColumn); if (chart.getYColumns().size() > 0) { String yColumn = chart.getYColumns().get(0); setYColumn(yColumn); } setXColor(chart.getXColor()); setYColor(chart.getYColor()); setYFunction(chart.getYFunction()); } public void refresh() { functionComboBox.setSelectedIndex(0); refreshX(); refreshY(); } public void refreshX() { setXColumn(null); } public void refreshY() { setYColumn(null); } public void setTitle(String title) { titleButton.setText(title); titleButton.setToolTipText(title); } public void setTitleFont(Font font) { titleButton.setFont(font); } public void setTitleColor(Color color) { titleButton.setForeground(color); } public void setTitleAlignment(byte alignment) { if (ChartTitle.LEFT_ALIGNMENT == alignment) { titleAlignment = GridBagConstraints.WEST; titleButton.setHorizontalAlignment(SwingConstants.LEFT); } else if (ChartTitle.CENTRAL_ALIGNMENT == alignment) { titleAlignment = GridBagConstraints.CENTER; titleButton.setHorizontalAlignment(SwingConstants.CENTER); } else { titleAlignment = GridBagConstraints.EAST; titleButton.setHorizontalAlignment(SwingConstants.RIGHT); } panel.remove(titleButton); panel.add(titleButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, titleAlignment, GridBagConstraints.NONE, new Insets(10, 10, 5, 10), 0, 0)); panel.revalidate(); panel.repaint(); } public void setMainBackground(Color color) { mainButton.setBackground(color); } public void setType(byte type) { ImageIcon image = null; if (ChartType.PIE == type) { image = ImageUtil.getImageIcon("chart_pie_main"); } else if (ChartType.BAR == type) { image = ImageUtil.getImageIcon("chart_bar_main"); } else if (ChartType.NEGATIVE_BAR == type) { image = ImageUtil.getImageIcon("chart_negative_bar_main"); } else if (ChartType.BAR_COMBO == type) { image = ImageUtil.getImageIcon("chart_bar_combo_main"); } else if (ChartType.STACKED_BAR == type) { image = ImageUtil.getImageIcon("chart_stacked_bar_main"); } else if (ChartType.STACKED_BAR_COMBO == type) { image = ImageUtil.getImageIcon("chart_stacked_bar_combo_main"); } else if (ChartType.HORIZONTAL_BAR == type) { image = ImageUtil.getImageIcon("chart_horizontal_bar_main"); } else if (ChartType.HORIZONTAL_STACKED_BAR == type) { image = ImageUtil.getImageIcon("chart_horizontal_stacked_bar_main"); } else if (ChartType.LINE == type) { image = ImageUtil.getImageIcon("chart_line_main"); } else if (ChartType.AREA == type) { image = ImageUtil.getImageIcon("chart_area_main"); } else if (ChartType.BUBBLE == type) { image = ImageUtil.getImageIcon("chart_bubble_main"); } previewFlashAction.setEnabled(!ChartType.hasNoFlashSupport(type)); if (image != null) { mainButton.setIcon(image); } reverseAxis(Globals.getChartDesignerPanel().getChart().getType().isHorizontal()); } public void setXColumn(String column) { xButton.setText(getShownText(column)); } public void setXColor(Color color) { xButton.setForeground(color); } public void setYColumn(String column) { yButton.setText(getShownText(column)); updateFunctions(getMarked(column)); } public boolean setYFunction(String function) { for (int i = 0, size = functionComboBox.getModel().getSize(); i < size; i++) { GFunction gfunction = (GFunction) functionComboBox.getModel().getElementAt(i); if (gfunction.getName().equals(function)) { functionComboBox.setSelectedIndex(i); return true; } } return false; } private String getShownText(String column) { if (column == null) { return I18NSupport.getString("chart.column.select"); } else { return "$C{" + column + "}"; } } public void setYColor(Color color) { yButton.setForeground(color); } private JToolBar createToolBar() { JToolBar toolBar = new JToolBar(); toolBar.putClientProperty("JToolBar.isRollover", Boolean.TRUE); // hide buttons borders toolBar.putClientProperty(Options.HEADER_STYLE_KEY, HeaderStyle.BOTH); toolBar.setBorderPainted(false); dataSourcesComboBox = new JComboBox(); dataSourcesComboBox.setPreferredSize(comboDim); dataSourcesComboBox.setMinimumSize(comboDim); dataSourcesComboBox.setMaximumSize(comboDim); dataSourcesComboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { //must reset parameters values because for a different data source // we may have different values. RuntimeParametersPanel.resetParametersValues(); } }); toolBar.add(dataSourcesComboBox); toolBar.add(Box.createHorizontalStrut(5)); toolBar.add(previewHTML5Action); toolBar.add(previewFlashAction); if (previewFlashAction.isSupported()) { previewFlashAction.setEnabled(false); } toolBar.add(previewImageAction); SwingUtil.addCustomSeparator(toolBar); toolBar.add(applyTemplateAction); toolBar.add(extractTemplateAction); return toolBar; } public void setColumns(List<NameType> columns) { try { this.columns = columns; List<String> columnNames = new ArrayList<String>(); List<Boolean> marked = new ArrayList<Boolean>(); for (NameType nt : columns) { columnNames.add(nt.getName()); if (!Number.class.isAssignableFrom(Class.forName(nt.getType()))) { marked.add(Boolean.TRUE); } else { marked.add(Boolean.FALSE); } } xButton.setItems(columnNames); yButton.setItems(columnNames, marked); } catch (Exception ex) { Show.error(ex); } } public Boolean getMarked(String column) { // columns is null for preview chart action from tree if (columns == null) { return Boolean.FALSE; } try { for (NameType nt : columns) { if (nt.getName().equals(column)) { return !Number.class.isAssignableFrom(Class.forName(nt.getType())); } } } catch (Exception ex) { Show.error(ex); } return Boolean.FALSE; } // xAxis and yAxis are reversed only visualy in the layout if we change // between a vertical and an orizontal chart type private void reverseAxis(boolean horizontal) { panel.remove(functionLabel); panel.remove(functionComboBox); panel.remove(yLabel); panel.remove(yButton.getPanel()); panel.remove(xLabel); panel.remove(xButton.getPanel()); if (!horizontal) { panel.add(functionLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 10, 0, 0), 0, 0)); panel.add(functionComboBox, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 10, 0, 0), 0, 0)); panel.add(yLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 10, 0, 0), 0, 0)); panel.add(yButton.getPanel(), new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 10, 0, 0), 0, 0)); panel.add(xLabel, new GridBagConstraints(1, 8, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 10, 5, 10), 0, 0)); panel.add(xButton.getPanel(), new GridBagConstraints(1, 9, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 10, 5, 10), 0, 0)); } else { panel.add(functionLabel, new GridBagConstraints(1, 6, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 10, 0, 0), 0, 0)); panel.add(functionComboBox, new GridBagConstraints(1, 7, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 10, 0, 0), 0, 0)); panel.add(yLabel, new GridBagConstraints(1, 8, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 10, 0, 0), 0, 0)); panel.add(yButton.getPanel(), new GridBagConstraints(1, 9, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 10, 0, 0), 0, 0)); panel.add(xLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 10, 5, 10), 0, 0)); panel.add(xButton.getPanel(), new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 10, 5, 10), 0, 0)); } repaint(); revalidate(); } public void selectConnectedDataSource() { DataSource connectedDS = DefaultDataSourceManager.getInstance().getConnectedDataSource(); if (connectedDS == null) { return; } dataSourcesComboBox.removeAllItems(); dataSourcesComboBox.setRenderer(new DataSourceComboBoxRenderer()); for (DataSource ds : DefaultDataSourceManager.getInstance().getDataSources(connectedDS.getDriver())) { dataSourcesComboBox.addItem(ds.getName()); } dataSourcesComboBox.setSelectedItem(connectedDS.getName()); } public DataSource getRunDataSource() { if (dataSourcesComboBox.getSelectedItem() == null) { return DefaultDataSourceManager.getInstance().getConnectedDataSource(); } else { return DefaultDataSourceManager.getInstance().getDataSource((String)dataSourcesComboBox.getSelectedItem()); } } class DataSourceComboBoxRenderer extends BasicComboBoxRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); if (-1 < index) { list.setToolTipText(value.toString()); } } else { setForeground(list.getForeground()); if (DefaultDataSourceManager.getInstance().getConnectedDataSource().getName().equals(value)) { setBackground(new Color(204, 255, 255)); } else { setBackground(list.getBackground()); } } setFont(list.getFont()); setText((value == null) ? "" : value.toString()); return this; } } }