/* GanttProject is an opensource project management tool. License: GPL3 Copyright (C) 2011 Dmitry Barashev, GanttProject Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package net.sourceforge.ganttproject; import biz.ganttproject.core.option.ChangeValueEvent; import biz.ganttproject.core.option.ChangeValueListener; import com.google.common.base.Preconditions; import com.google.common.base.Supplier; import net.sourceforge.ganttproject.chart.TimelineChart; import net.sourceforge.ganttproject.chart.overview.NavigationPanel; import net.sourceforge.ganttproject.chart.overview.ZoomingPanel; import net.sourceforge.ganttproject.gui.GanttImagePanel; import net.sourceforge.ganttproject.gui.UIFacade; import net.sourceforge.ganttproject.language.GanttLanguage; import javax.swing.*; import javax.swing.border.Border; import java.awt.*; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.ArrayList; import java.util.List; abstract class ChartTabContentPanel { private final TimelineChart myChart; private JSplitPane mySplitPane; private final List<Component> myPanels = new ArrayList<>(); private final UIFacade myUiFacade; private int myImageHeight; private Supplier<Integer> myHeaderHeight; private GanttImagePanel myImagePanel; ChartTabContentPanel(IGanttProject project, UIFacade workbenchFacade, TimelineChart chart) { NavigationPanel navigationPanel = new NavigationPanel(project, chart, workbenchFacade); ZoomingPanel zoomingPanel = new ZoomingPanel(workbenchFacade, chart); addChartPanel(zoomingPanel.getComponent()); addChartPanel(navigationPanel.getComponent()); myUiFacade = workbenchFacade; myChart = Preconditions.checkNotNull(chart); myUiFacade.getMainFrame().addWindowListener(new WindowAdapter() { @Override public void windowOpened(WindowEvent windowEvent) { updateTimelineHeight(); } }); } JComponent createContentComponent() { JPanel tabContentPanel = new JPanel(new BorderLayout()); final JPanel left = new JPanel(new BorderLayout()); final Box treeHeader = Box.createVerticalBox(); final JComponent buttonPanel = (JComponent) createButtonPanel(); JPanel buttonWrapper = new JPanel(new BorderLayout()); buttonWrapper.add(buttonPanel, BorderLayout.WEST); //button.setAlignmentX(Component.LEFT_ALIGNMENT); treeHeader.add(buttonWrapper); int defaultScaledHeight = (int)(UIFacade.DEFAULT_LOGO.getIconHeight() * myUiFacade.getDpiOption().getValue() / (1f * UIFacade.DEFAULT_DPI)); myImagePanel = new GanttImagePanel(myUiFacade.getLogo(), 300, defaultScaledHeight); myImageHeight = myImagePanel.getPreferredSize().height; JPanel imageWrapper = new JPanel(new BorderLayout()); imageWrapper.add(myImagePanel, BorderLayout.WEST); //myImagePanel.setAlignmentX(Component.LEFT_ALIGNMENT); treeHeader.add(imageWrapper); left.add(treeHeader, BorderLayout.NORTH); left.add(getTreeComponent(), BorderLayout.CENTER); Dimension minSize = new Dimension(0, 0); left.setMinimumSize(minSize); JPanel right = new JPanel(new BorderLayout()); final JComponent chartPanels = createChartPanels(); right.add(chartPanels, BorderLayout.NORTH); right.setBackground(new Color(0.93f, 0.93f, 0.93f)); right.add(getChartComponent(), BorderLayout.CENTER); right.setMinimumSize(minSize); mySplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); if (GanttLanguage.getInstance().getComponentOrientation() == ComponentOrientation.LEFT_TO_RIGHT) { mySplitPane.setLeftComponent(left); mySplitPane.setRightComponent(right); mySplitPane.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); mySplitPane.setDividerLocation(Math.min(300, left.getPreferredSize().width)); } else { mySplitPane.setRightComponent(left); mySplitPane.setLeftComponent(right); mySplitPane.setDividerLocation( Toolkit.getDefaultToolkit().getScreenSize().width - Math.min(300, left.getPreferredSize().width)); mySplitPane.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); } mySplitPane.setOneTouchExpandable(true); mySplitPane.resetToPreferredSizes(); tabContentPanel.add(mySplitPane, BorderLayout.CENTER); ChangeValueListener changeValueListener = new ChangeValueListener() { @Override public void changeValue(ChangeValueEvent event) { if (myUiFacade.getDpiOption().getValue() < 96) { return; } SwingUtilities.invokeLater(new Runnable() { @Override public void run() { alignTopPanelHeights(buttonPanel, chartPanels); myImagePanel.setScale(myUiFacade.getDpiOption().getValue() / (1f * UIFacade.DEFAULT_DPI)); myImageHeight = myImagePanel.getHeight(); updateTimelineHeight(); } }); } }; myUiFacade.getDpiOption().addChangeValueListener(changeValueListener, 2); return tabContentPanel; } private void alignTopPanelHeights(JComponent buttonPanel, JComponent chartPanels) { int maxHeight = Math.max(buttonPanel.getSize().height, chartPanels.getSize().height); if (buttonPanel.getHeight() < maxHeight) { //left.setBorder(BorderFactory.createEmptyBorder(maxHeight - buttonPanel.getHeight(), 0, 0, 0)); int diff = maxHeight - buttonPanel.getHeight(); Border emptyBorder = BorderFactory.createEmptyBorder((diff+1)/2, 0, diff/2, 0); buttonPanel.setBorder(emptyBorder); } if (chartPanels.getHeight() < maxHeight) { int diff = maxHeight - chartPanels.getHeight(); //Border emptyBorder = BorderFactory.createEmptyBorder((diff+1)/2, 0, diff/2, 0); //chartPanels.setBorder(emptyBorder); chartPanels.remove(chartPanels.getComponent(chartPanels.getComponentCount() - 1)); chartPanels.add(Box.createRigidArea(new Dimension(0, diff))); } } protected abstract Component getChartComponent(); protected abstract Component getTreeComponent(); protected abstract Component createButtonPanel(); int getDividerLocation() { return mySplitPane.getDividerLocation(); } void setDividerLocation(int location) { mySplitPane.setDividerLocation(location); } private JComponent createChartPanels() { Box panelsBox = Box.createHorizontalBox(); for (Component panel : myPanels) { panelsBox.add(panel); panelsBox.add(Box.createHorizontalStrut(10)); } return panelsBox; } void addChartPanel(Component panel) { myPanels.add(panel); } protected UIFacade getUiFacade() { return myUiFacade; } private void updateTimelineHeight() { int timelineHeight = myHeaderHeight.get() + myImageHeight; myChart.setTimelineHeight(timelineHeight); } void addTableResizeListeners(final Component tableContainer, final Component table) { myHeaderHeight = new Supplier<Integer>() { @Override public Integer get() { if (table.isShowing() && tableContainer.isShowing()) { Point tableLocation = table.getLocationOnScreen(); Point containerLocation = tableContainer.getLocationOnScreen(); return tableLocation.y - containerLocation.y; } else { return 0; } } }; ComponentAdapter componentListener = new ComponentAdapter() { @Override public void componentShown(ComponentEvent componentEvent) { updateTimelineHeight(); } @Override public void componentResized(ComponentEvent componentEvent) { updateTimelineHeight(); } @Override public void componentMoved(ComponentEvent componentEvent) { updateTimelineHeight(); } }; tableContainer.addComponentListener(componentListener); table.addComponentListener(componentListener); } public void setActive(boolean active) { if (active) { getTreeComponent().requestFocus(); updateTimelineHeight(); } } }