![JAR search and dependency download from the Maven repository](/logo.png)
org.netbeans.editor.StatusBar Maven / Gradle / Ivy
/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.editor;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.FontMetrics;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.Timer;
import javax.swing.BorderFactory;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.JComponent;
import javax.swing.border.Border;
import javax.swing.border.BevelBorder;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.text.JTextComponent;
import javax.swing.text.Caret;
import javax.swing.text.Document;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.UIManager;
/**
* Status bar support
*
* @author Miloslav Metelka
* @version 1.00
*/
public class StatusBar implements PropertyChangeListener, SettingsChangeListener, DocumentListener {
public static final String CELL_MAIN = "main"; // NOI18N
public static final String CELL_POSITION = "position"; // NOI18N
public static final String CELL_TYPING_MODE = "typing-mode"; // NOI18N
public static final String INSERT_LOCALE = "status-bar-insert"; // NOI18N
public static final String OVERWRITE_LOCALE = "status-bar-overwrite"; // NOI18N
private static final String[] POS_MAX_STRINGS = new String[] { "99999:999" }; // NOI18N
private static final Insets NULL_INSETS = new Insets(0, 0, 0, 0);
static final Border CELL_BORDER =
BorderFactory.createCompoundBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createMatteBorder(1,0,0,0,UIManager.getDefaults().getColor("control")), // NOI18N
BorderFactory.createCompoundBorder(
BorderFactory.createMatteBorder(0,0,1,1,UIManager.getDefaults().getColor("controlHighlight")), // NOI18N
BorderFactory.createLineBorder(UIManager.getDefaults().getColor("controlDkShadow")) // NOI18N
)
),
BorderFactory.createEmptyBorder(0, 2, 0, 2)
);
protected EditorUI editorUI;
/** The status bar panel into which the cells are added. */
private JPanel panel;
private boolean visible;
private Coloring coloring;
private Coloring boldColoring;
private List cellList = new ArrayList();
private Caret caret;
private CaretListener caretL;
private int caretDelay;
private boolean overwriteModeDisplayed;
private String insText;
private String ovrText;
private String caretPositionLocaleString;
private String insertModeLocaleString;
private String overwriteModeLocaleString;
static final long serialVersionUID =-6266183959929157349L;
public StatusBar(EditorUI editorUI) {
this.editorUI = editorUI;
caretDelay = 10;
caretL = new CaretListener(caretDelay);
insText = LocaleSupport.getString(INSERT_LOCALE);
ovrText = LocaleSupport.getString(OVERWRITE_LOCALE);
caretPositionLocaleString = LocaleSupport.getString("status-bar-caret-position"); //NOI18N
insertModeLocaleString = LocaleSupport.getString("status-bar-insert-mode"); //NOI18N
overwriteModeLocaleString = LocaleSupport.getString("status-bar-overwrite-mode"); //NOI18N
Settings.addSettingsChangeListener(this);
synchronized (editorUI.getComponentLock()) {
// if component already installed in EditorUI simulate installation
JTextComponent component = editorUI.getComponent();
if (component != null) {
propertyChange(new PropertyChangeEvent(editorUI,
EditorUI.COMPONENT_PROPERTY, null, component));
}
editorUI.addPropertyChangeListener(this);
}
}
public void settingsChange(SettingsChangeEvent evt) {
Class kitClass = Utilities.getKitClass(editorUI.getComponent());
String settingName = (evt != null) ? evt.getSettingName() : null;
if (kitClass != null) {
Coloring dc = editorUI.getDefaultColoring();
coloring = editorUI.getColoring(SettingsNames.STATUS_BAR_COLORING);
boldColoring = editorUI.getColoring(SettingsNames.STATUS_BAR_BOLD_COLORING);
// assign coloring
if (coloring != null) {
coloring = coloring.apply(dc);
} else {
coloring = dc;
}
// assign bold coloring
if (boldColoring != null) {
boldColoring = boldColoring.apply(dc);
} else {
boldColoring = dc;
}
// #50073
SwingUtilities.invokeLater(new Runnable(){
public void run(){
refreshPanel();
}
});
if (settingName == null || SettingsNames.STATUS_BAR_CARET_DELAY.equals(settingName)) {
caretDelay = SettingsUtil.getInteger(kitClass, SettingsNames.STATUS_BAR_CARET_DELAY,
SettingsDefaults.defaultStatusBarCaretDelay);
if (caretL != null) {
caretL.setDelay(caretDelay);
}
}
if (settingName == null || SettingsNames.STATUS_BAR_VISIBLE.equals(settingName)) {
boolean wantVisible = SettingsUtil.getBoolean(kitClass,
SettingsNames.STATUS_BAR_VISIBLE, SettingsDefaults.defaultStatusBarVisible);
setVisible(wantVisible);
}
}
}
private void documentUndo(DocumentEvent evt) {
Utilities.runInEventDispatchThread(new Runnable() {
public void run() {
// Clear the main cell
setText(CELL_MAIN, "");
}
});
}
public void insertUpdate(DocumentEvent evt) {
if (evt.getType() == DocumentEvent.EventType.REMOVE) { // undo
documentUndo(evt);
}
}
public void removeUpdate(DocumentEvent evt) {
if (evt.getType() == DocumentEvent.EventType.INSERT) { // undo
documentUndo(evt);
}
}
public void changedUpdate(DocumentEvent evt) {
}
protected JPanel createPanel() {
return new JPanel(new GridBagLayout());
}
public boolean isVisible() {
return visible;
}
public void setVisible(boolean v) {
if (v != visible) {
visible = v;
if (panel != null || visible) {
if (visible) { // need to refresh first
refreshPanel();
}
// fix for issue 13842
if (SwingUtilities.isEventDispatchThread()) {
getPanel().setVisible(visible);
} else {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
getPanel().setVisible(visible);
}
}
);
}
}
}
}
public final JPanel getPanel() {
if (panel == null) {
panel = createPanel();
initPanel();
}
return panel;
}
protected void initPanel() {
addCell(CELL_POSITION, POS_MAX_STRINGS).setHorizontalAlignment(
SwingConstants.CENTER);
addCell(CELL_TYPING_MODE, new String[] { insText, ovrText }).setHorizontalAlignment(
SwingConstants.CENTER);
setText(CELL_TYPING_MODE, insText);
addCell(CELL_MAIN, null);
}
public void propertyChange(PropertyChangeEvent evt) {
String propName = evt.getPropertyName();
if (EditorUI.COMPONENT_PROPERTY.equals(propName)) {
JTextComponent component = (JTextComponent)evt.getNewValue();
if (component != null) { // just installed
component.addPropertyChangeListener(this);
caret = component.getCaret();
if (caret != null) {
caret.addChangeListener(caretL);
}
Document doc = component.getDocument();
if (doc != null) {
doc.addDocumentListener(this);
}
settingsChange(null);
refreshPanel();
} else { // just deinstalled
component = (JTextComponent)evt.getOldValue();
component.removePropertyChangeListener(this);
caret = component.getCaret();
if (caret != null) {
caret.removeChangeListener(caretL);
}
Document doc = component.getDocument();
if (doc != null) {
doc.removeDocumentListener(this);
}
}
} else if ("caret".equals(propName)) { // NOI18N
if (caret != null) {
caret.removeChangeListener(caretL);
}
caret = (Caret)evt.getNewValue();
if (caret != null) {
caret.addChangeListener(caretL);
}
} else if ("document".equals(propName)) { // NOI18N
Document old = (Document)evt.getOldValue();
Document cur = (Document)evt.getNewValue();
if (old != null) {
old.removeDocumentListener(this);
}
if (cur != null) {
cur.addDocumentListener(this);
}
}
// Refresh the panel after each property-change
if (EditorUI.OVERWRITE_MODE_PROPERTY.equals(propName)) {
caretL.actionPerformed(null); // refresh immediately
} else { // not overwrite mode change
caretL.stateChanged(null);
}
}
private void applyColoring() {
}
public int getCellCount() {
return cellList.size();
}
public JLabel addCell(String name, String[] widestStrings) {
return addCell(-1, name, widestStrings);
}
public JLabel addCell(int i, String name, String[] widestStrings) {
Cell c = new Cell(name, widestStrings);
addCellImpl(i, c);
return c;
}
public void addCustomCell(int i, JLabel c) {
addCellImpl(i, c);
}
private void addCellImpl(int i, JLabel c) {
synchronized (cellList) {
ArrayList newCellList = new ArrayList(cellList);
int cnt = newCellList.size();
if (i < 0 || i > cnt) {
i = cnt;
}
newCellList.add(i, c);
cellList = newCellList;
updateCellBorders(i);
}
refreshPanel();
}
/** Manages cell borders so that left, right and inner cells have properly
* assigned borders for various LFs. Borders are special, installed by
* core into UIManager maps. */
private void updateCellBorders(int addedIndex) {
int cellCount = getCellCount();
Border innerBorder = (Border)UIManager.get("Nb.Editor.Status.innerBorder"); //NOI18N
Border leftBorder = (Border)UIManager.get("Nb.Editor.Status.leftBorder"); //NOI18N
Border rightBorder = (Border)UIManager.get("Nb.Editor.Status.rightBorder"); //NOI18N
Border onlyOneBorder = (Border)UIManager.get("Nb.Editor.Status.onlyOneBorder"); //NOI18N
if ((innerBorder == null) || (leftBorder == null) || (rightBorder == null)
|| onlyOneBorder == null) {
// don't modify borders at all if some is not available
return;
}
if (cellCount == 1) {
// only one cell
((JLabel)cellList.get(0)).setBorder(onlyOneBorder);
return;
}
if (addedIndex == 0) {
// added as first, updates second
((JLabel)cellList.get(0)).setBorder(leftBorder);
JLabel second = (JLabel)cellList.get(1);
second.setBorder(cellCount == 2 ? rightBorder : innerBorder);
} else if (addedIndex == cellCount - 1) {
// added as last, updates previous
((JLabel)cellList.get(cellCount - 1)).setBorder(rightBorder);
JLabel previous = (JLabel)cellList.get(cellCount - 2);
previous.setBorder(cellCount == 2 ? leftBorder : innerBorder);
} else {
// cell added inside
((JLabel)cellList.get(addedIndex)).setBorder(innerBorder);
}
}
public JLabel getCellByName(String name) {
Iterator i = cellList.iterator();
while (i.hasNext()) {
JLabel c = (JLabel)i.next();
if (name.equals(c.getName())) {
return c;
}
}
return null;
}
public String getText(String cellName) {
JLabel cell = getCellByName(cellName);
return (cell != null) ? cell.getText() : null;
}
public void setText(String cellName, String text) {
setText(cellName, text, null);
}
public void setBoldText(String cellName, String text) {
setText(cellName, text, boldColoring);
}
public void setText(String cellName, String text,
Coloring extraColoring) {
JLabel cell = getCellByName(cellName);
if (cell != null) {
Coloring c = coloring;
if (extraColoring != null) {
c = extraColoring.apply(c);
}
cell.setText(text);
if (CELL_POSITION.equals(cellName)){
cell.setToolTipText(caretPositionLocaleString);
}else if (CELL_TYPING_MODE.equals(cellName)){
cell.setToolTipText(insText.equals(text)? insertModeLocaleString : overwriteModeLocaleString);
}else{
cell.setToolTipText("".equals(text) ? null : text); //NOI18N
}
c.apply(cell);
}
}
/* Refresh the whole panel by removing all the components
* and adding only those that appear in the cell-list.
*/
private void refreshPanel() {
if (isVisible()) { // refresh only if visible
// Apply coloring to all cells
Iterator it = cellList.iterator();
while (it.hasNext()) {
JLabel c = (JLabel)it.next();
if (c instanceof Cell) {
coloring.apply(c);
}
}
// Layout cells
GridBagConstraints gc = new GridBagConstraints();
gc.gridx = GridBagConstraints.RELATIVE;
gc.gridwidth = 1;
gc.gridheight = 1;
it = cellList.iterator();
while (it.hasNext()) {
JLabel c = (JLabel)it.next();
boolean main = CELL_MAIN.equals(c.getName());
if (main) {
gc.fill = GridBagConstraints.HORIZONTAL;
gc.weightx = 1.0;
}
getPanel().add(c, gc);
if (main) {
gc.fill = GridBagConstraints.NONE;
gc.weightx = 0;
}
}
}
}
class CaretListener implements ChangeListener, ActionListener {
Timer timer;
CaretListener(int delay) {
timer = new Timer(delay, new WeakTimerListener(this));
timer.setRepeats(false);
}
void setDelay(int delay) {
timer.setInitialDelay(delay);
}
public void stateChanged(ChangeEvent evt) {
timer.restart();
}
public void actionPerformed(ActionEvent evt) {
Caret c = caret;
JTextComponent component = editorUI.getComponent();
if (component != null) {
if (c != null) {
BaseDocument doc = Utilities.getDocument(editorUI.getComponent());
if (doc != null) {
int pos = c.getDot();
String s = Utilities.debugPosition(doc, pos);
setText(CELL_POSITION, s);
}
}
Boolean b = (Boolean)editorUI.getProperty(EditorUI.OVERWRITE_MODE_PROPERTY);
boolean om = (b != null && b.booleanValue());
if (om != overwriteModeDisplayed) {
overwriteModeDisplayed = om;
setText(CELL_TYPING_MODE, overwriteModeDisplayed ? ovrText : insText);
}
}
}
}
static class Cell extends JLabel {
Dimension maxDimension;
String[] widestStrings;
static final long serialVersionUID =-2554600362177165648L;
Cell(String name, String[] widestStrings) {
setName(name);
setBorder(CELL_BORDER);
setOpaque(true);
this.widestStrings = widestStrings;
}
private void updateSize() {
Font f = getFont();
if (maxDimension == null) {
maxDimension = new Dimension();
}
if (f != null) {
Border b = getBorder();
Insets ins = (b != null) ? b.getBorderInsets(this) : NULL_INSETS;
FontMetrics fm = getFontMetrics(f);
int mw = fm.stringWidth(this.getText());
maxDimension.height = fm.getHeight() + ins.top + ins.bottom;
if (widestStrings != null) {
for (int i = 0; i < widestStrings.length; i++) {
mw = Math.max(mw, fm.stringWidth(widestStrings[i]));
}
}
maxDimension.width = mw + ins.left + ins.right;
}
}
public Dimension getPreferredSize() {
if (maxDimension == null) {
maxDimension = new Dimension();
}
return new Dimension(maxDimension);
}
public Dimension getMinimumSize(){
if (maxDimension == null) {
maxDimension = new Dimension();
}
return new Dimension(maxDimension);
}
public void setFont(Font f) {
super.setFont(f);
updateSize();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy