package com.vividsolutions.jump.workbench.ui.style; //[sstein 01.10.2005] changed to be able to work with real scale values import java.awt.Color; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.text.DecimalFormat; import javax.swing.ImageIcon; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import com.vividsolutions.jump.I18N; import com.vividsolutions.jump.util.MathUtil; import com.vividsolutions.jump.workbench.model.Layer; import com.vividsolutions.jump.workbench.ui.GUIUtil; import com.vividsolutions.jump.workbench.ui.LayerViewPanel; import com.vividsolutions.jump.workbench.ui.ValidatingTextField; import com.vividsolutions.jump.workbench.ui.images.IconLoader; import javax.swing.JButton; import org.openjump.core.ui.util.ScreenScale; public class ScaleStylePanel extends JPanel implements StylePanel { private static final ImageIcon MAX_SCALE_ICON = IconLoader.icon("Atom.gif"); private static final ImageIcon MIN_SCALE_ICON = GUIUtil.resize(IconLoader .icon("World2.gif"), 32); private JCheckBox enableScaleDependentRenderingCheckBox = null; private JLabel smallestScaleLabel = null; private JLabel largestScaleLabel = null; private JLabel smallestScale1Label = null; private JLabel largestScale1Label = null; private JLabel currentScale1Label = null; private ValidatingTextField smallestScaleTextField = null; private ValidatingTextField largestScaleTextField = null; private ValidatingTextField currentScaleTextField = null; private Layer layer; private LayerViewPanel panel; private JLabel currentScaleLabel = null; private JPanel fillerPanel = null; private JPanel spacerPanelInTopLeftCorner = null; private JLabel unitsPerPixelLabel = null; private JButton hideAboveCurrentScaleButton = null; private JButton hideBelowCurrentScaleButton = null; private static final Color TEXT_FIELD_BACKGROUND_COLOUR = new JTextField() .getBackground(); private JLabel smallestScaleIconLabel = null; private JLabel largestScaleIconLabel = null; private JPanel spacerPanelBelowCurrentScale = null; private JButton showAtThisScaleButton = null; private double scaleFactor = 0; private JPanel getFillerPanel() { if (fillerPanel == null) { fillerPanel = new JPanel(); } return fillerPanel; } public ScaleStylePanel(Layer layer, LayerViewPanel panel) { super(); initialize(); this.layer = layer; this.panel = panel; /** * [sstein : 01.10.2005] * modifications to show the real scale and not the internal values */ double internalScale = this.currentScale(); double realScale = ScreenScale.getHorizontalMapScale(panel.getViewport()); this.scaleFactor = internalScale / realScale; Double internalMinScale=layer.getMinScale(); Double realMinScale = null; if (internalMinScale != null){ //-- not sure to use Math.floor (with respect to zoom into cm space // but somehow necessary to avoid display like 6379.9999999 [sstein] realMinScale = new Double (Math.floor(internalMinScale.doubleValue()/this.scaleFactor)); } Double internalMaxScale = layer.getMaxScale(); Double realMaxScale = null; if(internalMaxScale != null){ realMaxScale = new Double(Math.floor(internalMaxScale.doubleValue()/this.scaleFactor)); } smallestScaleTextField.setText(formatScaleLosslessly(realMinScale)); largestScaleTextField .setText(formatScaleLosslessly(realMaxScale)); currentScaleTextField.setText(formatScaleLossily(realScale)); enableScaleDependentRenderingCheckBox.setSelected(layer .isScaleDependentRenderingEnabled()); updateComponents(); } protected double currentScale() { return 1d / panel.getViewport().getScale(); } private String formatScaleLosslessly(Double scale) { return scale != null ? formatScaleLosslessly(scale.doubleValue()) : ""; } private String formatScaleLosslessly(double scale) { // Unlike #formatCurrentScale, this method is lossless [Jon Aquino // 2005-03-31] return scale == (int) scale ? "" + (int) scale : "" + scale; } private void initialize() { GridBagConstraints gridBagConstraints21 = new GridBagConstraints(); GridBagConstraints gridBagConstraints18 = new GridBagConstraints(); smallestScaleIconLabel = new JLabel(); largestScaleIconLabel = new JLabel(); unitsPerPixelLabel = new JLabel(); GridBagConstraints gridBagConstraints15 = new GridBagConstraints(); GridBagConstraints gridBagConstraints14 = new GridBagConstraints(); GridBagConstraints gridBagConstraints12 = new GridBagConstraints(); GridBagConstraints gridBagConstraints11 = new GridBagConstraints(); largestScaleLabel = new JLabel(); smallestScaleLabel = new JLabel(); largestScale1Label = new JLabel(); currentScale1Label = new JLabel(); smallestScale1Label = new JLabel(); currentScaleLabel = new JLabel(); GridBagConstraints gridBagConstraints9 = new GridBagConstraints(); GridBagConstraints gridBagConstraints7 = new GridBagConstraints(); GridBagConstraints gridBagConstraints17 = new GridBagConstraints(); GridBagConstraints gridBagConstraints2 = new GridBagConstraints(); GridBagConstraints gridBagConstraints31 = new GridBagConstraints(); GridBagConstraints gridBagConstraints13 = new GridBagConstraints(); GridBagConstraints gridBagConstraints1 = new GridBagConstraints(); GridBagConstraints gridBagConstraints3 = new GridBagConstraints(); GridBagConstraints gridBagConstraints4 = new GridBagConstraints(); GridBagConstraints gridBagConstraints5 = new GridBagConstraints(); GridBagConstraints gridBagConstraints6 = new GridBagConstraints(); GridBagConstraints gridBagConstraints16 = new GridBagConstraints(); GridBagConstraints gridBagConstraints10 = new GridBagConstraints(); this.setLayout(new GridBagLayout()); gridBagConstraints1.gridx = 1; gridBagConstraints1.gridy = 4; smallestScaleLabel.setText(I18N.get("ui.style.ScaleStylePanel.smallest-scale")); //smallestScaleLabel.setToolTipText(I18N.get("ui.style.ScaleStylePanel.larger-units-pixel")); //[sstein] 8.Mar.2009 smallestScaleIconLabel.setIcon(MIN_SCALE_ICON); largestScaleIconLabel.setIcon(MAX_SCALE_ICON); gridBagConstraints5.gridx = 3; gridBagConstraints5.gridy = 6; smallestScale1Label.setText("1:"); currentScaleLabel.setText(I18N.get("ui.style.ScaleStylePanel.current-scale")); gridBagConstraints6.gridx = 3; gridBagConstraints6.gridy = 8; gridBagConstraints16.gridx = 3; gridBagConstraints16.gridy = 2; largestScale1Label.setText("1:"); currentScale1Label.setText("1:"); gridBagConstraints7.gridx = 4; gridBagConstraints7.gridy = 6; gridBagConstraints7.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints7.insets = new java.awt.Insets(0, 2, 0, 0); gridBagConstraints17.gridx = 4; gridBagConstraints17.gridy = 2; gridBagConstraints17.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints17.insets = new java.awt.Insets(0, 2, 0, 0); gridBagConstraints9.gridx = 4; gridBagConstraints9.gridy = 8; gridBagConstraints9.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints9.insets = new java.awt.Insets(0, 2, 0, 0); gridBagConstraints1.gridwidth = 5; gridBagConstraints1.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints3.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints3.insets = new java.awt.Insets(5, 5, 5, 0); gridBagConstraints4.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints4.insets = new java.awt.Insets(5, 5, 5, 0); gridBagConstraints5.insets = new java.awt.Insets(0, 10, 0, 0); gridBagConstraints6.insets = new java.awt.Insets(0, 10, 0, 0); gridBagConstraints16.insets = new java.awt.Insets(0, 10, 0, 0); gridBagConstraints16.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints10.gridx = 2; gridBagConstraints10.gridy = 2; gridBagConstraints10.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints10.insets = new java.awt.Insets(0, 5, 0, 0); gridBagConstraints10.gridwidth = 1; gridBagConstraints3.gridx = 2; gridBagConstraints3.gridy = 6; gridBagConstraints4.gridx = 2; gridBagConstraints4.gridy = 8; gridBagConstraints11.gridx = 7; gridBagConstraints11.gridy = 16; gridBagConstraints11.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints11.weightx = 1.0D; gridBagConstraints11.weighty = 1.0D; gridBagConstraints12.gridx = 0; gridBagConstraints12.gridy = 0; gridBagConstraints12.insets = new java.awt.Insets(2, 2, 2, 2); gridBagConstraints13.gridx = 4; gridBagConstraints13.gridy = 5; //unitsPerPixelLabel.setText(I18N.get("ui.style.ScaleStylePanel.units-pixel")); //[sstein] 8.Mar.2009 gridBagConstraints14.gridx = 7; gridBagConstraints14.gridy = 6; gridBagConstraints14.insets = new java.awt.Insets(4, 4, 4, 4); gridBagConstraints14.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints15.gridx = 7; gridBagConstraints15.gridy = 8; gridBagConstraints15.insets = new java.awt.Insets(4, 4, 4, 4); gridBagConstraints15.fill = java.awt.GridBagConstraints.HORIZONTAL; getShowAtThisScaleButton().setMargin(new Insets(0, 0, 0, 0)); getHideAboveCurrentScaleButton().setMargin(new Insets(0, 0, 0, 0)); getHideBelowCurrentScaleButton().setMargin(new Insets(0, 0, 0, 0)); getShowAtThisScaleButton().setMargin(new Insets(0, 0, 0, 0)); GUIUtil.shrinkFont(getHideAboveCurrentScaleButton()); GUIUtil.shrinkFont(getHideBelowCurrentScaleButton()); GUIUtil.shrinkFont(getShowAtThisScaleButton()); GUIUtil.shrinkFont(unitsPerPixelLabel); largestScaleLabel.setText(I18N.get("ui.style.ScaleStylePanel.largest-scale")); //largestScaleLabel.setToolTipText(I18N.get("ui.style.ScaleStylePanel.smaller-units-pixel")); //[sstein] 8.Mar.2009 gridBagConstraints2.gridx = 1; gridBagConstraints2.gridy = 6; gridBagConstraints31.gridx = 1; gridBagConstraints31.gridy = 8; gridBagConstraints2.insets = new java.awt.Insets(5, 10, 5, 0); gridBagConstraints31.insets = new java.awt.Insets(5, 10, 5, 0); gridBagConstraints18.gridx = 2; gridBagConstraints18.gridy = 3; gridBagConstraints21.gridx = 7; gridBagConstraints21.gridy = 2; gridBagConstraints21.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints21.insets = new java.awt.Insets(4, 4, 4, 4); this.add(getSpacerPanelInTopLeftCorner(), gridBagConstraints12); this.add(getShowAtThisScaleButton(), gridBagConstraints21); this.add(getEnableScaleDependentRenderingCheckBox(), gridBagConstraints1); this.add(currentScaleLabel, gridBagConstraints10); this.add(smallestScaleLabel, gridBagConstraints3); this.add(largestScaleLabel, gridBagConstraints4); this.add(getFillerPanel(), gridBagConstraints11); this.add(smallestScale1Label, gridBagConstraints5); this.add(largestScale1Label, gridBagConstraints6); this.add(unitsPerPixelLabel, gridBagConstraints13); this.add(getHideAboveCurrentScaleButton(), gridBagConstraints14); this.add(getHideBelowCurrentScaleButton(), gridBagConstraints15); this.add(currentScale1Label, gridBagConstraints16); this.add(smallestScaleIconLabel, gridBagConstraints2); this.add(largestScaleIconLabel, gridBagConstraints31); this.add(getSpacerPanelBelowCurrentScale(), gridBagConstraints18); this.add(getSmallestScaleTextField(), gridBagConstraints7); this.add(getLargestScaleTextField(), gridBagConstraints9); this.add(getCurrentScaleTextField(), gridBagConstraints17); } public String getTitle() { return I18N.get("ui.style.ScaleStylePanel.scale"); } public void updateStyles() { layer.getLayerManager().deferFiringEvents(new Runnable() { public void run() { layer.setMinScale(getSmallestScale()); layer.setMaxScale(getLargestScale()); layer .setScaleDependentRenderingEnabled(enableScaleDependentRenderingCheckBox .isSelected()); } }); layer.fireAppearanceChanged(); } public String validateInput() { if (getSmallestScale() != null && getLargestScale() != null && getLargestScale().doubleValue() > getSmallestScale() .doubleValue()) { return I18N.get("ui.style.ScaleStylePanel.units-pixel-at-smallest-scale-must-be-larger-than-units-pixel-at-largest-scale"); } if (getLargestScale() != null && getLargestScale().doubleValue() == 0) { return I18N.get("ui.style.ScaleStylePanel.units-pixel-at-largest-scale-must-be-greater-than-0"); } if (getSmallestScale() != null && getSmallestScale().doubleValue() == 0) { return I18N.get("ui.style.ScaleStylePanel.units-pixel-at-smallest-scale-must-be-greater-than-0"); } return null; } private Double getLargestScale() { //[sstein 01.10.2005] // change to be able to work with real scale values return largestScaleTextField.getText().trim().length() > 0 ? new Double( largestScaleTextField.getDouble()*this.scaleFactor) : null; } private Double getSmallestScale() { //[sstein 01.10.2005] // change to be able to work with real scale values return smallestScaleTextField.getText().trim().length() > 0 ? new Double( smallestScaleTextField.getDouble() * this.scaleFactor) : null; } private JCheckBox getEnableScaleDependentRenderingCheckBox() { if (enableScaleDependentRenderingCheckBox == null) { enableScaleDependentRenderingCheckBox = new JCheckBox(); enableScaleDependentRenderingCheckBox .setText(I18N.get("ui.style.ScaleStylePanel.only-show-layer-when-scale-is-between")); enableScaleDependentRenderingCheckBox .addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent e) { updateComponents(); } }); } return enableScaleDependentRenderingCheckBox; } private void updateComponents() { smallestScaleTextField .setBackground(enableScaleDependentRenderingCheckBox .isSelected() ? TEXT_FIELD_BACKGROUND_COLOUR : getBackground()); largestScaleTextField .setBackground(enableScaleDependentRenderingCheckBox .isSelected() ? TEXT_FIELD_BACKGROUND_COLOUR : getBackground()); unitsPerPixelLabel.setEnabled(enableScaleDependentRenderingCheckBox .isSelected()); hideAboveCurrentScaleButton .setEnabled(enableScaleDependentRenderingCheckBox.isSelected()); smallestScaleLabel.setEnabled(enableScaleDependentRenderingCheckBox .isSelected()); smallestScale1Label.setEnabled(enableScaleDependentRenderingCheckBox .isSelected()); smallestScaleTextField.setEnabled(enableScaleDependentRenderingCheckBox .isSelected()); hideBelowCurrentScaleButton .setEnabled(enableScaleDependentRenderingCheckBox.isSelected()); largestScaleLabel.setEnabled(enableScaleDependentRenderingCheckBox .isSelected()); largestScale1Label.setEnabled(enableScaleDependentRenderingCheckBox .isSelected()); largestScaleTextField.setEnabled(enableScaleDependentRenderingCheckBox .isSelected()); } private ValidatingTextField getSmallestScaleTextField() { if (smallestScaleTextField == null) { smallestScaleTextField = createValidatingTextField(); } return smallestScaleTextField; } private ValidatingTextField getLargestScaleTextField() { if (largestScaleTextField == null) { largestScaleTextField = createValidatingTextField(); } return largestScaleTextField; } private ValidatingTextField getCurrentScaleTextField() { if (currentScaleTextField == null) { currentScaleTextField = createValidatingTextField(); currentScaleTextField.setEditable(false); currentScaleTextField.setBackground(getBackground()); } return currentScaleTextField; } private ValidatingTextField createValidatingTextField() { // Use GreaterThanOrEqualValidator rather than GreaterThanValidator, // which won't let the user type a "0" even if they want to enter "0.1" // [Jon Aquino 2005-03-22] return new ValidatingTextField( "", 7, SwingConstants.LEFT, new ValidatingTextField.CompositeValidator( new ValidatingTextField.Validator[] { ValidatingTextField.DOUBLE_VALIDATOR, new ValidatingTextField.GreaterThanOrEqualValidator( 0) }), ValidatingTextField.DUMMY_CLEANER); } /** * Nicer formatting, but the expense of possibly losing precision. */ private String formatScaleLossily(double x) { if (1 <= x && x <= 1E6) { return new DecimalFormat("#").format(x); } if (1E-6 <= x && x <= 1) { return new DecimalFormat("0.000000").format(x); } return new DecimalFormat("0.#E0").format(x); } /** * This method initializes spacerPanel * * @return javax.swing.JPanel */ private JPanel getSpacerPanelInTopLeftCorner() { if (spacerPanelInTopLeftCorner == null) { spacerPanelInTopLeftCorner = new JPanel(); spacerPanelInTopLeftCorner.setLayout(new GridBagLayout()); } return spacerPanelInTopLeftCorner; } private JButton getHideAboveCurrentScaleButton() { if (hideAboveCurrentScaleButton == null) { hideAboveCurrentScaleButton = new JButton(); hideAboveCurrentScaleButton.setText(I18N.get("ui.style.ScaleStylePanel.hide-above-current-scale")); hideAboveCurrentScaleButton .addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent e) { //[sstein] changed to show real scale instead currentScale double realScale = 1/scaleFactor*currentScale(); smallestScaleTextField .setText(formatScaleLossily(roundFirstSignificantFigureUp(realScale))); } }); } return hideAboveCurrentScaleButton; } /** * Round the first significant figure up */ private double roundFirstSignificantFigureUp(double x) { return roundFirstSignificantFigure(x, 1); } /** * Round the first significant figure down */ private double roundFirstSignificantFigureDown(double x) { return roundFirstSignificantFigure(x, 0); } private static double roundFirstSignificantFigure(double x, int i) { double scale = Math.pow(10, Math.floor(MathUtil.base10Log(x))); int firstSignificantFigure = (int) Math.floor(x / scale); return (firstSignificantFigure + i) * scale; } private JButton getHideBelowCurrentScaleButton() { if (hideBelowCurrentScaleButton == null) { hideBelowCurrentScaleButton = new JButton(); hideBelowCurrentScaleButton.setText(I18N.get("ui.style.ScaleStylePanel.hide-below-current-scale")); hideBelowCurrentScaleButton .addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent e) { //[sstein] changed to show real scale instead currentScale double realScale = 1/scaleFactor*currentScale(); largestScaleTextField .setText(formatScaleLossily(roundFirstSignificantFigureDown(realScale))); } }); } return hideBelowCurrentScaleButton; } /** * This method initializes jPanel * * @return javax.swing.JPanel */ private JPanel getSpacerPanelBelowCurrentScale() { if (spacerPanelBelowCurrentScale == null) { spacerPanelBelowCurrentScale = new JPanel(); spacerPanelBelowCurrentScale.setLayout(new GridBagLayout()); spacerPanelBelowCurrentScale .setPreferredSize(new java.awt.Dimension(0, 20)); } return spacerPanelBelowCurrentScale; } /** * This method initializes showAtThisScaleButton * * @return javax.swing.JButton */ private JButton getShowAtThisScaleButton() { if (showAtThisScaleButton == null) { showAtThisScaleButton = new JButton(); showAtThisScaleButton.setText(I18N.get("ui.style.ScaleStylePanel.show-at-this-scale")); showAtThisScaleButton .addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent e) { if (!enableScaleDependentRenderingCheckBox .isSelected()) { enableScaleDependentRenderingCheckBox.doClick(); } if (getSmallestScale() != null && currentScale() > getSmallestScale() .doubleValue()) { getHideAboveCurrentScaleButton().doClick(); } if (getLargestScale() != null && currentScale() < getLargestScale() .doubleValue()) { getHideBelowCurrentScaleButton().doClick(); } } }); } return showAtThisScaleButton; } public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException { /* * System.out.println(roundFirstSignificantFigure(123, 1)); * System.out.println(roundFirstSignificantFigure(123, 0)); * System.out.println(roundFirstSignificantFigure(789, 1)); * System.out.println(roundFirstSignificantFigure(789, 0)); * System.out.println(roundFirstSignificantFigure(.00123, 1)); * System.out.println(roundFirstSignificantFigure(.00123, 0)); * System.out.println(roundFirstSignificantFigure(.00789, 1)); * System.out.println(roundFirstSignificantFigure(.00789, 0)); */ /* * System.out.println(new DecimalFormat("0.#E0").format(0.00000123)); * System.exit(0); */ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); JDialog dialog = new JDialog(); dialog.getContentPane().add(new ScaleStylePanel(new Layer() { { setMinScale(new Double(2)); setMaxScale(new Double(1)); } }, null) { protected double currentScale() { return .000000123; } }); dialog.pack(); dialog.setVisible(true); } } // @jve:decl-index=0:visual-constraint="10,10"