📄 basicspinnerui.java
字号:
* the editor to the <code>JSpinner</code> in an * <code>installUI</code> override. * <p> * Typically this method would be overridden to wrap the editor * with a container with a custom border, since one can't assume * that the editors border can be set directly. * <p> * The <code>replaceEditor</code> method is called when the spinners * editor is changed with <code>JSpinner.setEditor</code>. If you've * overriden this method, then you'll probably want to override * <code>replaceEditor</code> as well. * * @return the JSpinners editor JComponent, spinner.getEditor() by default * @see #installUI * @see #replaceEditor * @see JSpinner#getEditor */ protected JComponent createEditor() { JComponent editor = spinner.getEditor(); maybeRemoveEditorBorder(editor); installEditorBorderListener(editor); editor.setInheritsPopupMenu(true); updateEditorAlignment(editor); return editor; } /** * Called by the <code>PropertyChangeListener</code> when the * <code>JSpinner</code> editor property changes. It's the responsibility * of this method to remove the old editor and add the new one. By * default this operation is just: * <pre> * spinner.remove(oldEditor); * spinner.add(newEditor, "Editor"); * </pre> * The implementation of <code>replaceEditor</code> should be coordinated * with the <code>createEditor</code> method. * * @see #createEditor * @see #createPropertyChangeListener */ protected void replaceEditor(JComponent oldEditor, JComponent newEditor) { spinner.remove(oldEditor); maybeRemoveEditorBorder(newEditor); installEditorBorderListener(newEditor); newEditor.setInheritsPopupMenu(true); updateEditorAlignment(newEditor); spinner.add(newEditor, "Editor"); } private void updateEditorAlignment(JComponent editor) { if (editor instanceof JSpinner.DefaultEditor) { // if editor alignment isn't set in LAF, we get 0 (CENTER) here int alignment = UIManager.getInt("Spinner.editorAlignment"); JTextField text = ((JSpinner.DefaultEditor)editor).getTextField(); text.setHorizontalAlignment(alignment); } } /** * Remove the border around the inner editor component for LaFs * that install an outside border around the spinner, */ private void maybeRemoveEditorBorder(JComponent editor) { if (!UIManager.getBoolean("Spinner.editorBorderPainted")) { if (editor instanceof JPanel && editor.getBorder() == null && editor.getComponentCount() > 0) { editor = (JComponent)editor.getComponent(0); } if (editor != null && editor.getBorder() instanceof UIResource) { editor.setBorder(null); } } } /** * Remove the border around the inner editor component for LaFs * that install an outside border around the spinner, */ private void installEditorBorderListener(JComponent editor) { if (!UIManager.getBoolean("Spinner.editorBorderPainted")) { if (editor instanceof JPanel && editor.getBorder() == null && editor.getComponentCount() > 0) { editor = (JComponent)editor.getComponent(0); } if (editor != null && (editor.getBorder() == null || editor.getBorder() instanceof UIResource)) { editor.addPropertyChangeListener(getHandler()); } } } private void removeEditorBorderListener(JComponent editor) { if (!UIManager.getBoolean("Spinner.editorBorderPainted")) { if (editor instanceof JPanel && editor.getComponentCount() > 0) { editor = (JComponent)editor.getComponent(0); } if (editor != null) { editor.removePropertyChangeListener(getHandler()); } } } /** * Updates the enabled state of the children Components based on the * enabled state of the <code>JSpinner</code>. */ private void updateEnabledState() { updateEnabledState(spinner, spinner.isEnabled()); } /** * Recursively updates the enabled state of the child * <code>Component</code>s of <code>c</code>. */ private void updateEnabledState(Container c, boolean enabled) { for (int counter = c.getComponentCount() - 1; counter >= 0;counter--) { Component child = c.getComponent(counter); if (DefaultLookup.getBoolean(spinner, this, "Spinner.disableOnBoundaryValues", false)) { SpinnerModel model = spinner.getModel(); if (child.getName() == "Spinner.nextButton" && model.getNextValue() == null) { child.setEnabled(false); } else if (child.getName() == "Spinner.previousButton" && model.getPreviousValue() == null) { child.setEnabled(false); } else { child.setEnabled(enabled); } } else { child.setEnabled(enabled); } if (child instanceof Container) { updateEnabledState((Container)child, enabled); } } } /** * Installs the keyboard Actions onto the JSpinner. * * @since 1.5 */ protected void installKeyboardActions() { InputMap iMap = getInputMap(JComponent. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); SwingUtilities.replaceUIInputMap(spinner, JComponent. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, iMap); LazyActionMap.installLazyActionMap(spinner, BasicSpinnerUI.class, "Spinner.actionMap"); } /** * Returns the InputMap to install for <code>condition</code>. */ private InputMap getInputMap(int condition) { if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) { return (InputMap)DefaultLookup.get(spinner, this, "Spinner.ancestorInputMap"); } return null; } static void loadActionMap(LazyActionMap map) { map.put("increment", nextButtonHandler); map.put("decrement", previousButtonHandler); } /** * Returns the baseline. * * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} * @see javax.swing.JComponent#getBaseline(int, int) * @since 1.6 */ public int getBaseline(JComponent c, int width, int height) { super.getBaseline(c, width, height); JComponent editor = spinner.getEditor(); Insets insets = spinner.getInsets(); width = width - insets.left - insets.right; height = height - insets.top - insets.bottom; if (width >= 0 && height >= 0) { int baseline = editor.getBaseline(width, height); if (baseline >= 0) { return insets.top + baseline; } } return -1; } /** * Returns an enum indicating how the baseline of the component * changes as the size changes. * * @throws NullPointerException {@inheritDoc} * @see javax.swing.JComponent#getBaseline(int, int) * @since 1.6 */ public Component.BaselineResizeBehavior getBaselineResizeBehavior( JComponent c) { super.getBaselineResizeBehavior(c); return spinner.getEditor().getBaselineResizeBehavior(); } /** * A handler for spinner arrow button mouse and action events. When * a left mouse pressed event occurs we look up the (enabled) spinner * that's the source of the event and start the autorepeat timer. The * timer fires action events until any button is released at which * point the timer is stopped and the reference to the spinner cleared. * The timer doesn't start until after a 300ms delay, so often the * source of the initial (and final) action event is just the button * logic for mouse released - which means that we're relying on the fact * that our mouse listener runs after the buttons mouse listener. * <p> * Note that one instance of this handler is shared by all slider previous * arrow buttons and likewise for all of the next buttons, * so it doesn't have any state that persists beyond the limits * of a single button pressed/released gesture. */ private static class ArrowButtonHandler extends AbstractAction implements FocusListener, MouseListener, UIResource { final javax.swing.Timer autoRepeatTimer; final boolean isNext; JSpinner spinner = null; JButton arrowButton = null; ArrowButtonHandler(String name, boolean isNext) { super(name); this.isNext = isNext; autoRepeatTimer = new javax.swing.Timer(60, this); autoRepeatTimer.setInitialDelay(300); } private JSpinner eventToSpinner(AWTEvent e) { Object src = e.getSource(); while ((src instanceof Component) && !(src instanceof JSpinner)) { src = ((Component)src).getParent(); } return (src instanceof JSpinner) ? (JSpinner)src : null; } public void actionPerformed(ActionEvent e) { JSpinner spinner = this.spinner; if (!(e.getSource() instanceof javax.swing.Timer)) { // Most likely resulting from being in ActionMap. spinner = eventToSpinner(e); if (e.getSource() instanceof JButton) { arrowButton = (JButton)e.getSource(); } } else { if (arrowButton!=null && !arrowButton.getModel().isPressed() && autoRepeatTimer.isRunning()) { autoRepeatTimer.stop(); spinner = null; arrowButton = null; } } if (spinner != null) { try { int calendarField = getCalendarField(spinner); spinner.commitEdit(); if (calendarField != -1) { ((SpinnerDateModel)spinner.getModel()). setCalendarField(calendarField); } Object value = (isNext) ? spinner.getNextValue() : spinner.getPreviousValue(); if (value != null) { spinner.setValue(value); select(spinner); } } catch (IllegalArgumentException iae) { UIManager.getLookAndFeel().provideErrorFeedback(spinner); } catch (ParseException pe) { UIManager.getLookAndFeel().provideErrorFeedback(spinner); } } } /** * If the spinner's editor is a DateEditor, this selects the field * associated with the value that is being incremented. */ private void select(JSpinner spinner) { JComponent editor = spinner.getEditor(); if (editor instanceof JSpinner.DateEditor) { JSpinner.DateEditor dateEditor = (JSpinner.DateEditor)editor; JFormattedTextField ftf = dateEditor.getTextField(); Format format = dateEditor.getFormat(); Object value; if (format != null && (value = spinner.getValue()) != null) { SpinnerDateModel model = dateEditor.getModel(); DateFormat.Field field = DateFormat.Field.ofCalendarField( model.getCalendarField()); if (field != null) { try { AttributedCharacterIterator iterator = format. formatToCharacterIterator(value); if (!select(ftf, iterator, field) && field == DateFormat.Field.HOUR0) { select(ftf, iterator, DateFormat.Field.HOUR1); } } catch (IllegalArgumentException iae) {} } } } } /** * Selects the passed in field, returning true if it is found, * false otherwise. */ private boolean select(JFormattedTextField ftf, AttributedCharacterIterator iterator, DateFormat.Field field) { int max = ftf.getDocument().getLength(); iterator.first(); do { Map attrs = iterator.getAttributes(); if (attrs != null && attrs.containsKey(field)){ int start = iterator.getRunStart(field); int end = iterator.getRunLimit(field);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -