
com.globalmentor.swing.unicode.UnicodeStatusBar Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of globalmentor-swing Show documentation
Show all versions of globalmentor-swing Show documentation
GlobalMentor Java Swing library.
The newest version!
/*
* Copyright © 1996-2009 GlobalMentor, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.globalmentor.swing.unicode;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import static com.globalmentor.java.Objects.*;
import com.globalmentor.swing.*;
import com.globalmentor.swing.text.TextComponents;
import com.globalmentor.text.Unicode;
import com.globalmentor.unicode.*;
/**
* A status bar showing Unicode code point value, name, and category.
* @author Garret Wilson
*/
public class UnicodeStatusBar extends StatusBar {
/** The last known position in a document, or -1
if not known. */
private int position = -1;
/** @return The last known position in a document, or -1
if not known. */
protected int getPosition() {
return position;
};
/** The label for a Unicode character value. */
protected final JLabel unicodeCharacterValueLabel;
/** The label for a Unicode character name. */
protected final JLabel unicodeCharacterNameLabel;
/**
* The caret listener that updates the status bar in response to a caret event.
* @see #updateStatus(CaretEvent)
*/
protected final CaretListener caretListener = new CaretListener() {
public void caretUpdate(final CaretEvent caretEvent) {
updateStatus(caretEvent);
}
};
/**
* The document listener that updates the status bar in response to a document event.
* @see #updateStatus(DocumentEvent)
*/
protected final DocumentListener documentListener = new DocumentListener() {
public void insertUpdate(final DocumentEvent documentEvent) {
updateStatus(documentEvent);
}
public void removeUpdate(final DocumentEvent documentEvent) {
updateStatus(documentEvent);
}
public void changedUpdate(final DocumentEvent documentEvent) {
updateStatus(documentEvent);
}
};
/**
* The document change listener that updates the document listener in response to a document change.
* @see #onDocumentChange(Document, Document)
*/
protected final PropertyChangeListener documentPropertyChangeListener = new PropertyChangeListener() {
public void propertyChange(final PropertyChangeEvent propertyChangeEvent) {
onDocumentChange(asInstance(propertyChangeEvent.getOldValue(), Document.class), asInstance(propertyChangeEvent.getNewValue(), Document.class));
}
};
/** Default constructor. */
public UnicodeStatusBar() {
this(true); //construct a panel and initialize it
}
/**
* Constructor with optional initialization.
* @param initialize true
if the toolbar should initialize itself by calling the initialization methods.
*/
public UnicodeStatusBar(final boolean initialize) {
super("Unicode Character Information", false); //construct the parent class without initializing it //TODO i18n
unicodeCharacterValueLabel = createStatusLabel(); //create a label for the Unicode character value
unicodeCharacterNameLabel = createStatusLabel(); //create a label for the Unicode character name
if(initialize) //if we should initialize
initialize(); //initialize the panel
}
/** Initializes the user interface. */
public void initializeUI() {
super.initializeUI(); //do the default user interface initialization
addStatusComponent(unicodeCharacterValueLabel); //add the Unicode character value label
addStatusComponent(unicodeCharacterNameLabel); //add the Unicode character name label
}
/** The currently displayed Unicode character, or null
if no character is currently being displayed. */
private UnicodeCharacter unicodeCharacter = null;
/** @return The currently displayed Unicode character, or null
if no character is currently being displayed. */
public UnicodeCharacter getUnicodeCharacter() {
return unicodeCharacter;
}
/** The currently displayed Unicode code point, or -1
if no code point is currently being displayed. */
private int codePoint = -1;
/** @return The currently displayed Unicode code point, or -1
if no code point is currently being displayed. */
public int getCodePoint() {
return codePoint;
}
/**
* Sets the Unicode character status by changing the displayed code point.
* @param codePoint The Unicode code point, or -1
for no code point.
*/
public void setCodePoint(final int codePoint) {
if(getCodePoint() != codePoint) { //if the code point is really changing
this.codePoint = codePoint; //save the code point
unicodeCharacter = codePoint >= 0 ? UnicodeData.getUnicodeCharacter(codePoint) : null; //if a code point was indicated, try to get a character corresponding to the code point
if(codePoint >= 0) { //if a valid code point was indicated
unicodeCharacterValueLabel.setText(Unicode.getCodePointString(codePoint)); //show the Unicode character value
if(unicodeCharacter != null) { //if we found Unicode character information
unicodeCharacterNameLabel.setText(unicodeCharacter.getUniqueCharacterName()); //show the Unicode character name
} else { //if we didn't find a Unicode character
unicodeCharacterNameLabel.setText(""); //show no Unicode character name
}
} else { //if we don't have a valid Unicode code point
unicodeCharacterValueLabel.setText(""); //show no Unicode character value
unicodeCharacterNameLabel.setText(""); //show no Unicode character name
}
}
}
/**
* Updates the status, such as the Unicode character information labels, for the text component character at the caret position.
* @param textComponent The text component that holds Unicode characters.
*/
public void updateStatus(final JTextComponent textComponent) {
updateStatus(textComponent.getDocument(), textComponent.getCaretPosition()); //update the status for the text component for the character at the given position
}
/**
* Updates the status, such as the Unicode character information labels, for the text component character at the given position. The given position is saved.
* @param document The document that holds Unicode characters.
* @param position The position for which the status should be shown.
*/
public void updateStatus(final Document document, final int position) {
try {
final String unicodeString = document.getText(position, 1); //get the single character at the given position
setCodePoint(unicodeString.charAt(0)); //set the code point to the character at the given position
} catch(BadLocationException e) { //if the caret isn't at a valid position
unicodeCharacter = null; //show that we don't have a Unicode character
}
this.position = position; //save the position
}
/**
* Updates the status when a text component caret is updated by updating the Unicode status labels to represent the character under the caret.
* @param caretEvent The event that holds information about the caret change.
* @see #updateStatus(JTextComponent, int)
*/
protected void updateStatus(final CaretEvent caretEvent) {
final Object source = caretEvent.getSource(); //get the source of the event
if(source instanceof JTextComponent) { //if a text component made the change
updateStatus(((JTextComponent)source).getDocument(), caretEvent.getDot()); //update the status for the character under the new cursor position
}
}
/**
* Updates the status when a text component document is changed if that change appears under the cursor.
* @param documentEvent The event that holds information about the document change.
* @see #updateStatus(JTextComponent, int)
*/
protected void updateStatus(final DocumentEvent documentEvent) {
final int position = getPosition(); //get our current position
final int eventOffset = documentEvent.getOffset(); //get the event's offset
if(position >= eventOffset && position < eventOffset + documentEvent.getLength()) { //if our position is within the event range
updateStatus(documentEvent.getDocument(), position); //update the status for the current character under the position
}
}
/**
* Updates the document changes listeners based upon the change of document.
* @param oldDocument The old document, or null
if there was no previous document.
* @param newDocument The new document, or null
if there is no new document.
*/
protected void onDocumentChange(final Document oldDocument, final Document newDocument) {
if(oldDocument != null) { //if there was a previous document
oldDocument.removeDocumentListener(documentListener); //stop listening for document changes from the old document
}
if(newDocument != null) { //if there is a new document
newDocument.addDocumentListener(documentListener); //listen for document changes in the new document
}
}
/**
* Attaches this status bar to a text component so that it will be updated when the text component changes.
* @param textComponent The text component to which the status bar should be attached.
*/
public void attach(final JTextComponent textComponent) {
textComponent.addCaretListener(caretListener); //listen for caret events
textComponent.getDocument().addDocumentListener(documentListener); //listen for document changes in the document
textComponent.addPropertyChangeListener(TextComponents.DOCUMENT_PROPERTY, documentPropertyChangeListener); //listen for document changes
updateStatus(textComponent); //update the status for the text component, which will save the current caret position
}
/**
* Detaches this status bar from a text component so that it will no longer be be updated when the text component changes.
* @param textComponent The text component from which the status bar should be detached.
*/
public void detach(final JTextComponent textComponent) {
textComponent.removeCaretListener(caretListener); //stop listening for caret events
textComponent.getDocument().removeDocumentListener(documentListener); //stop listening for document changes in the document
textComponent.removePropertyChangeListener(TextComponents.DOCUMENT_PROPERTY, documentPropertyChangeListener); //listen for document changes
position = -1; //show that we no longer represent a valid position
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy