package org.geogebra.desktop.gui.properties; import java.awt.Component; import java.awt.FlowLayout; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.SwingConstants; import org.geogebra.common.gui.SetLabels; import org.geogebra.common.gui.UpdateFonts; import org.geogebra.common.gui.dialog.options.model.SliderModel; import org.geogebra.common.gui.dialog.options.model.SliderModel.ISliderOptionsListener; import org.geogebra.common.kernel.Kernel; import org.geogebra.common.kernel.arithmetic.MyDouble; import org.geogebra.common.kernel.arithmetic.NumberValue; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.main.Localization; import org.geogebra.desktop.gui.AngleTextField; import org.geogebra.desktop.gui.dialog.PropertiesPanelD; import org.geogebra.desktop.gui.inputfield.MyTextFieldD; import org.geogebra.desktop.main.AppD; /** * panel for numeric slider * * @author Markus Hohenwarter */ public class SliderPanel extends JPanel implements ActionListener, FocusListener, UpdateablePropertiesPanel, SetLabels, UpdateFonts, ISliderOptionsListener { /** * */ private static final long serialVersionUID = 1L; private SliderModel model; private AngleTextField tfMin, tfMax; private JTextField tfWidth; private JTextField[] tfields; private JLabel[] tLabels; private JLabel lbWidthUnit; private JCheckBox cbSliderFixed, cbRandom; private JComboBox coSliderHorizontal; private AppD app; private AnimationStepPanel stepPanel; private AnimationSpeedPanel speedPanel; private Kernel kernel; private PropertiesPanelD propPanel; private JPanel intervalPanel, sliderPanel, animationPanel; private boolean useTabbedPane; private boolean actionPerforming; private final Localization loc; public SliderPanel(AppD app, PropertiesPanelD propPanel, boolean useTabbedPane, boolean includeRandom) { this.app = app; this.loc = app.getLocalization(); kernel = app.getKernel(); model = new SliderModel(app, this); this.propPanel = propPanel; this.useTabbedPane = useTabbedPane; model.setIncludeRandom(includeRandom); intervalPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5)); sliderPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5)); animationPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5)); cbSliderFixed = new JCheckBox("", true); cbSliderFixed.addActionListener(this); sliderPanel.add(cbSliderFixed); cbRandom = new JCheckBox(); cbRandom.addActionListener(this); sliderPanel.add(cbRandom); coSliderHorizontal = new JComboBox(); coSliderHorizontal.addActionListener(this); sliderPanel.add(coSliderHorizontal); tfMin = new AngleTextField(6, app); tfMax = new AngleTextField(6, app); tfWidth = new MyTextFieldD(app, 4); lbWidthUnit = new JLabel(""); tfields = new MyTextFieldD[3]; tLabels = new JLabel[3]; tfields[0] = tfMin; tfields[1] = tfMax; tfields[2] = tfWidth; int numPairs = tLabels.length; // add textfields for (int i = 0; i < numPairs; i++) { JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT)); tLabels[i] = new JLabel("", SwingConstants.LEADING); p.add(tLabels[i]); JTextField textField = tfields[i]; tLabels[i].setLabelFor(textField); textField.addActionListener(this); textField.addFocusListener(this); p.add(textField); if (i == 2) { p.add(lbWidthUnit); } p.setAlignmentX(Component.LEFT_ALIGNMENT); if (i < 2) { intervalPanel.add(p); } else { sliderPanel.add(p); } } // add increment to intervalPanel stepPanel = new AnimationStepPanel(app); stepPanel.setPartOfSliderPanel(); intervalPanel.add(stepPanel); speedPanel = new AnimationSpeedPanel(app); speedPanel.setPartOfSliderPanel(); animationPanel.add(speedPanel); setLabels(); } private void initPanels() { removeAll(); // put together interval, slider options, animation panels if (useTabbedPane) { setLayout(new FlowLayout()); JTabbedPane tabbedPane = new JTabbedPane(); tabbedPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); tabbedPane.addTab(loc.getMenu("Interval"), intervalPanel); tabbedPane.addTab(loc.getMenu("Slider"), sliderPanel); tabbedPane.addTab(loc.getMenu("Animation"), animationPanel); add(tabbedPane); } else { // no tabs setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); intervalPanel.setBorder( BorderFactory.createTitledBorder(loc.getPlain("Interval"))); sliderPanel.setBorder( BorderFactory.createTitledBorder(loc.getPlain("Slider"))); animationPanel.setBorder(BorderFactory .createTitledBorder(loc.getPlain("Animation"))); add(intervalPanel); add(Box.createVerticalStrut(5)); add(sliderPanel); add(Box.createVerticalStrut(5)); add(animationPanel); } } @Override public void setLabels() { initPanels(); cbSliderFixed.setText(loc.getMenu("fixed")); cbRandom.setText(loc.getMenu("Random")); String[] comboStr = { loc.getMenu("horizontal"), loc.getMenu("vertical") }; int selectedIndex = coSliderHorizontal.getSelectedIndex(); coSliderHorizontal.removeActionListener(this); coSliderHorizontal.removeAllItems(); for (int i = 0; i < comboStr.length; ++i) { coSliderHorizontal.addItem(comboStr[i]); } coSliderHorizontal.setSelectedIndex(selectedIndex); coSliderHorizontal.addActionListener(this); tLabels[0].setText(loc.getMenu("min") + ":"); tLabels[1].setText(loc.getMenu("max") + ":"); tLabels[2].setText(loc.getMenu("Width") + ":"); model.setLabelForWidthUnit(); stepPanel.setLabels(); speedPanel.setLabels(); } @Override public JPanel updatePanel(Object[] geos) { stepPanel.updatePanel(geos); speedPanel.updatePanel(geos); model.setGeos(geos); if (!model.checkGeos()) { return null; } for (int i = 0; i < tfields.length; i++) { tfields[i].removeActionListener(this); } coSliderHorizontal.removeActionListener(this); cbSliderFixed.removeActionListener(this); cbRandom.removeActionListener(this); model.updateProperties(); for (int i = 0; i < tfields.length; i++) { tfields[i].addActionListener(this); } coSliderHorizontal.addActionListener(this); cbSliderFixed.addActionListener(this); cbRandom.addActionListener(this); return this; } /** * handle textfield changes */ @Override public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if (source == cbSliderFixed) { doCheckBoxActionPerformed((JCheckBox) source); } else if (source == cbRandom) { doRandomActionPerformed((JCheckBox) source); } else if (source == coSliderHorizontal) { doComboBoxActionPerformed((JComboBox) source); } else { doTextFieldActionPerformed((JTextField) e.getSource()); } } private void doCheckBoxActionPerformed(JCheckBox source) { model.applyFixed(source.isSelected()); updatePanel(model.getGeos()); } private void doRandomActionPerformed(JCheckBox source) { model.applyRandom(source.isSelected()); updatePanel(model.getGeos()); } private void doComboBoxActionPerformed(JComboBox source) { model.applyDirection(source.getSelectedIndex()); updatePanel(model.getGeos()); } private void doTextFieldActionPerformed(JTextField source) { actionPerforming = true; String inputText = source.getText().trim(); boolean emptyString = "".equals(inputText); NumberValue value = new MyDouble(kernel, Double.NaN); if (!emptyString) { value = kernel.getAlgebraProcessor().evaluateToNumeric(inputText, false); } if (source == tfMin) { model.applyMin(value); } else if (source == tfMax) { model.applyMax(value); } else if (source == tfWidth) { model.applyWidth(value.getDouble()); } if (propPanel != null) { propPanel.updateSelection(model.getGeos()); } else { updatePanel(model.getGeos()); } actionPerforming = false; } @Override public void focusGained(FocusEvent arg0) { // only handle focus lost } @Override public void focusLost(FocusEvent e) { if (!actionPerforming) { doTextFieldActionPerformed((JTextField) e.getSource()); } } @Override public void updateFonts() { Font font = app.getPlainFont(); cbSliderFixed.setFont(font); cbRandom.setFont(font); coSliderHorizontal.setFont(font); for (int i = 0; i < tLabels.length; ++i) { tLabels[i].setFont(font); } tfMin.setFont(font); tfMax.setFont(font); tfWidth.setFont(font); for (int i = 0; i < tfields.length; ++i) { tfields[i].setFont(font); } stepPanel.updateFonts(); speedPanel.updateFonts(); } @Override public void updateVisualStyle(GeoElement geo) { // TODO Auto-generated method stub } @Override public void setMinText(String text) { tfMin.setText(text); } @Override public void setMaxText(String text) { tfMax.setText(text); } @Override public void setWidthText(String text) { tfWidth.setText(text); } @Override public void selectFixed(boolean value) { cbSliderFixed.setSelected(value); } @Override public void selectRandom(boolean value) { cbRandom.setSelected(value); } @Override public void setRandomVisible(boolean value) { cbRandom.setVisible(value); } @Override public void setSliderDirection(int index) { coSliderHorizontal.setSelectedIndex(index); } @Override public void setWidthUnitText(String text) { lbWidthUnit.setText(text); } }