📄 basictextui.java
字号:
* Returns the starting offset into the model for this view. * * @return the starting offset */ public int getStartOffset() { if (view != null) { return view.getStartOffset(); } return getElement().getStartOffset(); } /** * Returns the ending offset into the model for this view. * * @return the ending offset */ public int getEndOffset() { if (view != null) { return view.getEndOffset(); } return getElement().getEndOffset(); } /** * Gets the element that this view is mapped to. * * @return the view */ public Element getElement() { if (view != null) { return view.getElement(); } return editor.getDocument().getDefaultRootElement(); } /** * Breaks this view on the given axis at the given length. * * @param axis may be either X_AXIS or Y_AXIS * @param len specifies where a break is desired in the span * @param the current allocation of the view * @return the fragment of the view that represents the given span * if the view can be broken, otherwise null */ public View breakView(int axis, float len, Shape a) { throw new Error("Can't break root view"); } /** * Determines the resizability of the view along the * given axis. A value of 0 or less is not resizable. * * @param axis may be either X_AXIS or Y_AXIS * @return the weight */ public int getResizeWeight(int axis) { if (view != null) { return view.getResizeWeight(axis); } return 0; } /** * Sets the view size. * * @param width the width * @param height the height */ public void setSize(float width, float height) { if (view != null) { view.setSize(width, height); } } /** * Fetches the container hosting the view. This is useful for * things like scheduling a repaint, finding out the host * components font, etc. The default implementation * of this is to forward the query to the parent view. * * @return the container */ public Container getContainer() { return editor; } /** * Fetches the factory to be used for building the * various view fragments that make up the view that * represents the model. This is what determines * how the model will be represented. This is implemented * to fetch the factory provided by the associated * EditorKit unless that is null, in which case this * simply returns the BasicTextUI itself which allows * subclasses to implement a simple factory directly without * creating extra objects. * * @return the factory */ public ViewFactory getViewFactory() { EditorKit kit = getEditorKit(editor); ViewFactory f = kit.getViewFactory(); if (f != null) { return f; } return BasicTextUI.this; } private View view; } /** * Handles updates from various places. If the model is changed, * this class unregisters as a listener to the old model and * registers with the new model. If the document model changes, * the change is forwarded to the root view. If the focus * accelerator changes, a new keystroke is registered to request * focus. */ class UpdateHandler implements PropertyChangeListener, DocumentListener, LayoutManager2, UIResource { // --- PropertyChangeListener methods ----------------------- /** * This method gets called when a bound property is changed. * We are looking for document changes on the editor. */ public final void propertyChange(PropertyChangeEvent evt) { Object oldValue = evt.getOldValue(); Object newValue = evt.getNewValue(); String propertyName = evt.getPropertyName(); if ((oldValue instanceof Document) || (newValue instanceof Document)) { if (oldValue != null) { ((Document)oldValue).removeDocumentListener(this); } if (newValue != null) { ((Document)newValue).addDocumentListener(this); if ("document".equals(propertyName)) { BasicTextUI.this.propertyChange(evt); modelChanged(); return; } } modelChanged(); } if (JTextComponent.FOCUS_ACCELERATOR_KEY.equals(propertyName)) { updateFocusAcceleratorBinding(true); } else if ("componentOrientation".equals(propertyName)) { // Changes in ComponentOrientation require the views to be // rebuilt. modelChanged(); } else if ("font".equals(propertyName)) { modelChanged(); } else if ("transferHandler".equals(propertyName)) { DropTarget dropTarget = editor.getDropTarget(); if (dropTarget instanceof UIResource) { if (defaultDropTargetListener == null) { defaultDropTargetListener = new TextDropTargetListener(); } try { dropTarget.addDropTargetListener(defaultDropTargetListener); } catch (TooManyListenersException tmle) { // should not happen... swing drop target is multicast } } } BasicTextUI.this.propertyChange(evt); } // --- DocumentListener methods ----------------------- /** * The insert notification. Gets sent to the root of the view structure * that represents the portion of the model being represented by the * editor. The factory is added as an argument to the update so that * the views can update themselves in a dynamic (not hardcoded) way. * * @param e The change notification from the currently associated * document. * @see DocumentListener#insertUpdate */ public final void insertUpdate(DocumentEvent e) { Document doc = e.getDocument(); Object o = doc.getProperty("i18n"); if (o instanceof Boolean) { Boolean i18nFlag = (Boolean) o; if (i18nFlag.booleanValue() != i18nView) { // i18n flag changed, rebuild the view i18nView = i18nFlag.booleanValue(); modelChanged(); return; } } // normal insert update Rectangle alloc = (painted) ? getVisibleEditorRect() : null; rootView.insertUpdate(e, alloc, rootView.getViewFactory()); } /** * The remove notification. Gets sent to the root of the view structure * that represents the portion of the model being represented by the * editor. The factory is added as an argument to the update so that * the views can update themselves in a dynamic (not hardcoded) way. * * @param e The change notification from the currently associated * document. * @see DocumentListener#removeUpdate */ public final void removeUpdate(DocumentEvent e) { Rectangle alloc = (painted) ? getVisibleEditorRect() : null; rootView.removeUpdate(e, alloc, rootView.getViewFactory()); } /** * The change notification. Gets sent to the root of the view structure * that represents the portion of the model being represented by the * editor. The factory is added as an argument to the update so that * the views can update themselves in a dynamic (not hardcoded) way. * * @param e The change notification from the currently associated * document. * @see DocumentListener#changeUpdate */ public final void changedUpdate(DocumentEvent e) { Rectangle alloc = (painted) ? getVisibleEditorRect() : null; rootView.changedUpdate(e, alloc, rootView.getViewFactory()); } // --- LayoutManager2 methods -------------------------------- /** * Adds the specified component with the specified name to * the layout. * @param name the component name * @param comp the component to be added */ public void addLayoutComponent(String name, Component comp) { // not supported } /** * Removes the specified component from the layout. * @param comp the component to be removed */ public void removeLayoutComponent(Component comp) { if (constraints != null) { // remove the constraint record constraints.remove(comp); } } /** * Calculates the preferred size dimensions for the specified * panel given the components in the specified parent container. * @param parent the component to be laid out * * @see #minimumLayoutSize */ public Dimension preferredLayoutSize(Container parent) { // should not be called (JComponent uses UI instead) return null; } /** * Calculates the minimum size dimensions for the specified * panel given the components in the specified parent container. * @param parent the component to be laid out * @see #preferredLayoutSize */ public Dimension minimumLayoutSize(Container parent) { // should not be called (JComponent uses UI instead) return null; } /** * Lays out the container in the specified panel. This is * implemented to position all components that were added * with a View object as a constraint. The current allocation * of the associated View is used as the location of the * component. * <p> * A read-lock is acquired on the document to prevent the * view tree from being modified while the layout process * is active. * * @param parent the component which needs to be laid out */ public void layoutContainer(Container parent) { if ((constraints != null) && (! constraints.isEmpty())) { Rectangle alloc = getVisibleEditorRect(); if (alloc != null) { Document doc = editor.getDocument(); if (doc instanceof AbstractDocument) { ((AbstractDocument)doc).readLock(); } try { rootView.setSize(alloc.width, alloc.height); Enumeration components = constraints.keys(); while (components.hasMoreElements()) { Component comp = (Component) components.nextElement(); View v = (View) constraints.get(comp); Shape ca = calculateViewPosition(alloc, v); if (ca != null) { Rectangle compAlloc = (ca instanceof Rectangle) ? (Rectangle) ca : ca.getBounds(); comp.setBounds(compAlloc); } } } finally { if (doc instanceof AbstractDocument) { ((AbstractDocument)doc).readUnlock(); } } } } } /** * Find the Shape representing the given view. */ Shape calculateViewPosition(Shape alloc, View v) { int pos = v.getStartOffset(); View child = null; for (View parent = rootView; (parent != null) && (parent != v); parent = child) { int index = parent.getViewIndex(pos, Position.Bias.Forward); alloc = parent.getChildAllocation(index, alloc); child = parent.getView(index); } return (child != null) ? alloc : null; } /** * Adds the specified component to the layout, using the specified * constraint object. We only store those components that were added * with a constraint that is of type View. * * @param comp the component to be added * @param constraint where/how the component is added to the layout. */ public void addLayoutComponent(Component comp, Object constraint) { if (constraint instanceof View) { if (constraints == null) { constraints = new Hashtable(7); } constraints.put(comp, constraint); } } /** * Returns the maximum size of this component. * @see java.awt.Component#getMinimumSize() * @see java.awt.Component#getPreferredSize() * @see LayoutManager */ public Dimension maximumLayoutSize(Container target) { // should not be called (JComponent uses UI instead) return null; } /** * Returns the alignment along the x axis. This specifies how * the component would like to be aligned relative to other * components. The value should be a number between 0 and 1 * where 0 represents alignment along the origin, 1 is aligned * the furthest away from the origin, 0.5 is centered, etc. */ public float getLayoutAlignmentX(Container target) { return 0.5f; } /** * Returns the alignment along the y axis. This specifies how * the component would like to be aligned relative to other * components. The value should be a number between 0 and 1 * where 0 represents alignment along the origin, 1 is aligned * the furthest away from the origin, 0.5 is centered
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -