Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added convenient text field alignment capabilities #896

Merged
merged 1 commit into from
Jan 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.fxmisc.richtext.model.SimpleEditableStyledDocument;

import javafx.scene.text.TextAlignment;
import javafx.scene.text.TextFlow;

/**
Expand All @@ -20,4 +21,9 @@ public InlineCssTextField( String text ) {
getUndoManager().forgetHistory();
getUndoManager().mark();
}

@Override
protected void changeAlignment( TextAlignment txtAlign ) {
setParagraphStyle( 0, "-fx-text-alignment: "+ txtAlign );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import org.fxmisc.richtext.model.SimpleEditableStyledDocument;

import javafx.scene.text.TextAlignment;

/**
* A TextField that uses style classes, i.e. <code>getStyleClass().add(String)</code>, to define the styles of text segments.
* <p>Use CSS Style Class ".styled-text-field" for styling the control.
Expand Down Expand Up @@ -55,4 +57,10 @@ public void replace( int start, int end, String text, String styleClass ) {
public void setStyleClass( int from, int to, String styleClass ) {
setStyle( from, to, Collections.singletonList( styleClass ) );
}

@Override
protected void changeAlignment( TextAlignment txtAlign ) {
// Set to style class as defined in "styled-text-field-caspian.css" AND "styled-text-field-modena.css"
setParagraphStyle( 0, Collections.singletonList( txtAlign.toString().toLowerCase() ) );
}
}
59 changes: 49 additions & 10 deletions richtextfx/src/main/java/org/fxmisc/richtext/StyledTextField.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.fxmisc.richtext;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.regex.Pattern;
Expand All @@ -10,6 +12,10 @@
import javafx.beans.NamedArg;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ObjectPropertyBase;
import javafx.css.CssMetaData;
import javafx.css.StyleConverter;
import javafx.css.Styleable;
import javafx.css.StyleableObjectProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.AccessibleRole;
Expand All @@ -22,21 +28,30 @@
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.text.TextAlignment;
import javafx.scene.text.TextFlow;

/**
* A text field whose segment generic has been specified to be a {@link String}. How the text
* will be styled is not yet specified in this class, but use {@link StyleClassedTextField} for a style class
* approach to styling the text and {@link InlineCssTextField} for an inline css approach to styling the text.
*
* <p>Use CSS Style Class ".styled-text-field" for styling the control.</p>
*
* @param <PS> type of paragraph style
* @param <S> type of style that can be applied to text.
*
* @author Jurgen
*/
public class StyledTextField<PS, S> extends StyledTextArea
public abstract class StyledTextField<PS, S> extends StyledTextArea<PS, S>
{
private final Pattern VERTICAL_WHITESPACE = Pattern.compile( "\\v+" );
private final static List<CssMetaData<? extends Styleable, ?>> CSS_META_DATA_LIST;

private final static CssMetaData<StyledTextField,TextAlignment> TEXT_ALIGNMENT = new CustomCssMetaData<>(
"-fx-alignment", (StyleConverter<?,TextAlignment>) StyleConverter.getEnumConverter(TextAlignment.class),
TextAlignment.LEFT, s -> (StyleableObjectProperty) s.textAlignmentProperty()
);
private final static Pattern VERTICAL_WHITESPACE = Pattern.compile( "\\v+" );
private final static String STYLE_SHEET;
private final static double HEIGHT;
static {
Expand All @@ -46,6 +61,9 @@ public class StyledTextField<PS, S> extends StyledTextArea
globalCSS = "styled-text-field-"+ globalCSS.toLowerCase() +".css";
STYLE_SHEET = StyledTextField.class.getResource( globalCSS ).toExternalForm();

List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(GenericStyledArea.getClassCssMetaData());
styleables.add(TEXT_ALIGNMENT); CSS_META_DATA_LIST = Collections.unmodifiableList(styleables);

// Ugly hack to get a TextFields default height :(
// as it differs between Caspian, Modena, etc.
TextField tf = new TextField( "GetHeight" );
Expand All @@ -54,6 +72,7 @@ public class StyledTextField<PS, S> extends StyledTextArea
}

private boolean selectAll = true;
private StyleableObjectProperty<TextAlignment> textAlignment;


public StyledTextField(@NamedArg("initialParagraphStyle") PS initialParagraphStyle,
Expand All @@ -76,7 +95,7 @@ public StyledTextField(@NamedArg("initialParagraphStyle") PS initialParagraphSty
KE.consume();
}
else if ( KE.getCode() == KeyCode.TAB ) {
traverse( this.getParent(), this, KE.isShiftDown() ? -1 : +1 );
traverse( this.getParent(), this, KE.isShiftDown() ? -1 : +1 );
KE.consume();
}
});
Expand Down Expand Up @@ -136,16 +155,23 @@ else if ( target.isVisible() && ! target.isDisabled() && target.isFocusTraversab
return traverse( p.getParent(), p, dir ); // up
}


public void setText( String text )
{
replaceText( text );
/**
* Specifies how the text should be aligned when there is empty space within the TextField.
* To configure via CSS use {@code -fx-alignment:} and values from {@link javafx.scene.text.TextAlignment}.
*/
public final ObjectProperty<TextAlignment> textAlignmentProperty() {
if (textAlignment == null) {
textAlignment = new CustomStyleableProperty<>( TextAlignment.LEFT, "textAlignment", this, TEXT_ALIGNMENT );
textAlignment.addListener( (ob,ov,alignment) -> changeAlignment( alignment ) );
}
return textAlignment;
}
public final TextAlignment getAlignment() { return textAlignment == null ? TextAlignment.LEFT : textAlignment.getValue(); }
public final void setAlignment( TextAlignment value ) { textAlignmentProperty().setValue( value ); }
protected abstract void changeAlignment( TextAlignment txtAlign );

/**
* The action handler associated with this text field, or
* {@code null} if no action handler is assigned.
*
* The action handler associated with this text field, or {@code null} if no action handler is assigned.
* The action handler is normally called when the user types the ENTER key.
*/
private ObjectProperty<EventHandler<ActionEvent>> onAction = new ObjectPropertyBase<EventHandler<ActionEvent>>() {
Expand Down Expand Up @@ -174,8 +200,21 @@ public void replaceText( int start, int end, String text )
super.replaceText( start, end, VERTICAL_WHITESPACE.matcher( text ).replaceAll( " " ) );
}

public void setText( String text )
{
replaceText( text );
}

/** This is a <b>no op</b> for text fields and therefore marked as <i>deprecated</i>. */
@Override @Deprecated public void setWrapText( boolean value ) {}
/** This <u>always</u> returns <b>false</b> for styled text fields. */
@Override public boolean isWrapText() { return false; }


@Override public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
return CSS_META_DATA_LIST;
}
public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
return CSS_META_DATA_LIST;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.styled-text-field
{
-fx-cursor: text;
-fx-text-fill: -fx-text-inner-color;
-fx-text-fill: -fx-text-inner-color;
-fx-background-color: -fx-shadow-highlight-color, -fx-text-box-border, -fx-control-inner-background;
-fx-background-insets: 0, 1, 2;
-fx-background-radius: 3, 2, 2;
Expand All @@ -15,9 +15,24 @@
}
.styled-text-field:disabled
{
-fx-opacity: -fx-disabled-opacity;
-fx-opacity: -fx-disabled-opacity;
}
.styled-text-field .main-selection
.main-selection
{
-fx-fill: #0093ff;
-fx-fill: #0093ff;
}

// Text alignment classes for StyleClassedTextField

.center
{
-fx-text-alignment: center;
}
.left
{
-fx-text-alignment: left;
}
.right
{
-fx-text-alignment: right;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,24 @@
}
.styled-text-field:disabled
{
-fx-opacity: 0.4;
-fx-opacity: 0.4;
}
.styled-text-field .main-selection
.main-selection
{
-fx-fill: #0096C9;
-fx-fill: #0096C9;
}

// Text alignment classes for StyleClassedTextField

.center
{
-fx-text-alignment: center;
}
.left
{
-fx-text-alignment: left;
}
.right
{
-fx-text-alignment: right;
}