- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 swing 应用程序,它覆盖 javax.swing.text.Document 以将基础文档的内容限制为某些字符和文本长度。我想将我的应用程序移植到 Javafx,但我不知道此类是否有 Javafx 等效项。有没有办法在Javafx中替换它?
我的类正在做的是包装文档以添加新功能(在我的情况下是有限的)。许多方法仅遵循我使用的底层文档,但其中一些方法增加了我的限制,这些限制是:
行长度限制
行数限制
大写限制
字符限制
public class ConstrainedDocument implements Document {
protected Document document = null;
private boolean limitLength = false;
private boolean limitLines = false;
private int maxLength = -1;
private int maxLines = -1;
private boolean limitText = false;
private String allowedText = null;
private boolean uppercase = false;
/**
* Constructor.
*
* @param doc the document
*/
public ConstrainedDocument(Document doc) {
this.document = doc;
}
/**
* Constructor.
*/
public ConstrainedDocument() {
this.document = new PlainDocument();
}
public Document getDocument() {
return document;
}
/**
* Limits the allowed length for each line of the document.
*
* @param maxLength the maximum line length
*/
public void setMaximumLength(int maxLength) {
this.maxLength = maxLength;
this.limitLength = true;
}
/**
* Limits the allowed number of lines for the document.
*
* @param maxLines the maximum number of lines
*/
public void setMaximumLines(int maxLines) {
this.maxLines = maxLines;
this.limitLines = true;
}
/**
* Limits the characters allowed to compose the document.
*
* @param allowedText the String defining the allowed characters
*/
public void setAllowedText(String allowedText) {
this.allowedText = allowedText;
this.limitText = true;
}
/**
* Forces only upper case.
*
* @param uppercase true if only upper case are forced
*/
public void setUpperCase(boolean uppercase) {
this.uppercase = uppercase;
}
/**
* Resets all the limitations and settings for this document.
*/
public void resetLimitations() {
this.limitText = false;
this.limitLength = false;
this.limitLines = false;
}
/**
* Returns the allowed length for each line of the document.
*
* @return the maximum line length
*/
public int getMaximumLineLength() {
return maxLength;
}
/**
* Returns the allowed number of lines for the document.
*
* @return the maximum number of lines
*/
public int getMaximumLines() {
return maxLines;
}
/**
* Returns true if the maximum length of the text is set.
*
* @return true if the maximum length of the text is set
*
* @see #getMaximumLineLength()
*/
public boolean isLineLengthLimited() {
return limitLength;
}
/**
* Returns true if the number of allowed lines is limited.
*
* @return true if the maximum number of lines is set
*
* @see #getMaximumLines()
*/
public boolean isLinesLimited() {
return limitLines;
}
/**
* Returns the characters allowed to compose the document.
*
* @return the allowed characters as a string
*/
public String getAllowedText() {
return allowedText;
}
/**
* Returns true if the allowed characters are limited.
*
* @return true if the allowed characters are limited
*
* @see #getAllowedText()
*/
public boolean isTextLimited() {
return limitText;
}
/**
* Returns true if the insertion is forced to upper case characters.
*
* @return true if the insertion is forced to upper case characters
*/
public boolean isUpperCase() {
return uppercase;
}
/**
* Extends the remove method from the parent Document class to fire remove events
* when lines are removed.
*/
@Override
public void remove(int offset, int length) throws BadLocationException {
document.remove(offset, length);
}
/**
* Extends the insertString method from the parent Document class. This adds :
* <ul>
* <li>the ability to force upper case characters insertion if the {@link #isUpperCase()}
* property is set</li>
* <li>the ability to block insertion of unauthorized characters if the {@link #isTextLimited()}
* property is set. In that case, the text is limited to the {@link #getAllowedText()} characters</li>
* <li>the ability to limit the number of lines if the {@link #isLinesLimited()} property is set. In
* that case, the number of allowed lines is limited to {@link #getMaximumLines()}</li>
* <li>the ability to limit the length of each line if the {@link #isLineLengthLimited()} property
* is set. In that case, the length for each line is limited to {@link #getMaximumLineLength()}</li>
* </ul>
* <p>
* It also fire insertion events when lines are inserted.</p>
*/
@Override
public void insertString(int offset, String inputStr, AttributeSet a) throws BadLocationException {
String str = inputStr;
// handle showSpaces, upper case and characters limitation
if (uppercase || limitText) {
StringBuilder buf = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (uppercase) {
c = Character.toUpperCase(c);
}
if (limitText) {
if (allowedText.indexOf(c) != -1) {
buf.append(c);
}
} else {
buf.append(c);
}
}
str = buf.toString();
}
Element root = document.getDefaultRootElement();
AbstractDocument.LeafElement elt = (AbstractDocument.LeafElement) root.getElement(root.getElementIndex(offset));
// Gets the text to insert, taking care of adding new lines in the process
str = getTextToInsert(root, elt, str);
if (str.length() > 0) {
document.insertString(offset, str, a);
}
// if only the length of the text is limited
}
/**
* Returns the text to insert on the current line.
*
* @param root the root element of the Document
* @param elt the leaf element, interface the line of text where to insert the text
* @param t the String to insert
*/
protected String getTextToInsert(Element root, AbstractDocument.LeafElement elt, String t) {
// Gets the length of the line where to insert the text
int begin = elt.getStartOffset();
int end = elt.getEndOffset();
int length = end - begin - 1;
// Gets the number of lines
int lineCount = root.getElementCount();
// iterate through the text to insert, taking care of the line length
// and number of lines limitation
StringBuilder buf = new StringBuilder();
for (int i = 0; i < t.length(); i++) {
char c = t.charAt(i);
// if this is a new line, we must check if we are allowed to add a new line
if (c == '\n') {
// we are not allowed to add a new line
if (limitLines && lineCount >= maxLines) {
break;
} else {
// ok, we can add a new line
buf.append(c);
lineCount++;
length = 0;
}
// this is not a new line character, we add the character if we can
} else {
// if no line length limitation, we just add the character
if (!limitLength) {
buf.append(c);
} else if (length >= maxLength) {
// else current length >= maximum line length, we try to add a new line
// not allowed, finish to add
if (limitLines && lineCount >= maxLines) {
break;
} else {
// adding a new line is allowed, there is remaining available lines
buf.append('\n').append(c);
lineCount++;
length = 1;
}
// current length < maximum line length, we just add the character
} else {
buf.append(c);
length++;
}
}
}
return buf.toString();
}
/**
* Return the text of this Document. Special spaces characters will be trasnformed to "real" spaces.
*/
@Override
public String getText(int offset, int length) throws BadLocationException {
String text = document.getText(offset, length);
return text;
}
/**
* get the offset position in the Document for the selected line.
*
* @param line the selected line
* @return the offset position.
*/
public int getOffsetPosition(int line) {
int offset = 0;
int count = 0;
if (line == 0) {
return offset;
}
Element root = document.getDefaultRootElement();
try {
for (int i = 0; i < root.getElementCount(); i++) {
AbstractDocument.LeafElement elt = (AbstractDocument.LeafElement) root.getElement(i);
offset = elt.getStartOffset();
String text = getText(elt.getStartOffset(), elt.getEndOffset() - elt.getStartOffset());
if (count == line) {
break;
}
if (text.charAt(text.length() - 1) == '\n') {
count++;
}
}
} catch (BadLocationException e) {
e.printStackTrace();
}
return offset;
}
@Override
public int getLength() {
return document.getLength();
}
@Override
public void render(Runnable runnable) {
document.render(runnable);
}
@Override
public void addDocumentListener(DocumentListener listener) {
document.addDocumentListener(listener);
}
@Override
public void removeDocumentListener(DocumentListener listener) {
document.removeDocumentListener(listener);
}
@Override
public void addUndoableEditListener(UndoableEditListener listener) {
document.addUndoableEditListener(listener);
}
@Override
public void removeUndoableEditListener(UndoableEditListener listener) {
document.removeUndoableEditListener(listener);
}
@Override
public Element getDefaultRootElement() {
return document.getDefaultRootElement();
}
@Override
public Element[] getRootElements() {
return document.getRootElements();
}
@Override
public Position getEndPosition() {
return document.getEndPosition();
}
@Override
public Position getStartPosition() {
return document.getStartPosition();
}
@Override
public Position createPosition(int i) throws BadLocationException {
return document.createPosition(i);
}
@Override
public void getText(int i, int i0, Segment segment) throws BadLocationException {
document.getText(i, i0, segment);
}
@Override
public Object getProperty(Object key) {
return document.getProperty(key);
}
@Override
public void putProperty(Object key, Object value) {
document.putProperty(key, value);
}
}
最佳答案
可以使用 TextFormatter
在 JavaFX 中实现此功能.
例如,这个快速示例实现了最大文本长度。 Swing 示例中的其他功能可以类似地实现:
package org.jamesd.examples.maxtextlength;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) {
TextArea textArea = new TextArea();
Spinner<Integer> maxLengthSpinner = new Spinner<>(10, 200, 100);
maxLengthSpinner.valueProperty().addListener((obs, oldLength, newLength) ->
textArea.setText(textArea.getText().substring(0, Math.min(newLength, textArea.getLength())))
);
textArea.setTextFormatter(new TextFormatter<String>(change -> {
int proposedTextLength = change.getControlNewText().length();
if (proposedTextLength > maxLengthSpinner.getValue()) {
// truncate text to maximum allowed length:
int newTextLength = change.getText().length();
int delta = proposedTextLength - maxLengthSpinner.getValue();
change.setText(change.getText().substring(0, newTextLength - delta));
// adjust caret:
change.setCaretPosition(change.getCaretPosition() - delta);
change.setAnchor(change.getAnchor() - delta);
}
return change;
}));
Label length = new Label();
length.textProperty().bind(textArea.textProperty().map(String::length).map(len -> "Length: "+len));
length.setPadding(new Insets(5));
HBox controls = new HBox(5, new Label("Max text length:"), maxLengthSpinner);
controls.setPadding(new Insets(5));
controls.setAlignment(Pos.CENTER);
BorderPane root = new BorderPane(textArea);
root.setBottom(length);
root.setTop(controls);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
我有时发现 TextFormatter
的使用有点不直观(尽管它非常强大)。您可能想引用这个excellent tutorial .
关于swing - Javafx 替代 swing javax.swing.text.Document,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77193601/
我正在开发一个摆动程序以显示多张图片。并且可以旋转图片(每个图片都以JComponent实现)。 问题是,当图片旋转时,JComponent的边框不会改变,因此图片会被剪切。 有什么办法也可以旋转边框
我有一个 JPanel 和一个 JButton 向量,我想将每个按钮添加到面板。 我遇到的问题是我有一个代表按钮向量的变量 btns,但宏函数只是将它视为一个符号,而不是一个向量。有没有办法以某种方式
我有一个 swing 应用程序,它覆盖 javax.swing.text.Document 以将基础文档的内容限制为某些字符和文本长度。我想将我的应用程序移植到 Javafx,但我不知道此类是否有 J
我有一个带有面板的简单应用程序,我想在单击它时暂停并重新开始绘画。 object ModulusPatterns extends SimpleSwingApplication { var dela
我似乎无法在 Swing 中强制布局。我有一个 JComponent添加到 JLayeredPane我在 JComponent 上设置了边框.然后,我想立即重新绘制所有内容 - 而不是像 invali
我有一个 Swing 应用程序,我想通过将外部文件从 Windows 资源管理器拖到应用程序上来导入外部文件。我有这个基本功能工作。但是,我想将默认的拖放光标图标更改为应用程序适当的光标。当鼠标键被按
我想在我的 Scala 摆动应用程序中使用一棵树,但该组件在 API 中不可用。 是否包装了 JTree存在吗? 如果没有,你对制作有什么建议吗? 谢谢 最佳答案 即使您可以在 Scala 程序中直接
我目前正在努力使我的 Swing 应用程序看起来更好。我想在这些方面实现一些目标: 这个想法是让每个框都有一个漂亮的标题,背景类似于上图。使用基本的 Swing 组件,我能得到的最接近的东西是添加 T
这是我在 Scala 中使用 Swing 的第一次实验,并且对下面的代码有一些疑问。它所做的只是生成一个带有可改变颜色的彩色矩形的窗口。请随时回答一个或任何一个问题。 1) 我在下面使用了 Java
一个愚蠢的问题,但我真的无法让它起作用:我在 Swing 应用程序中有一些长时间运行的过程,可能需要几分钟。我想在此过程进行时向用户显示进度对话框。我还想阻止用户执行进一步的操作,例如在进程进行时按下
如何获取秋千组件的默认背景色?我的意思是JPanel的默认背景色? 最佳答案 要获取创建面板时将使用的 DEFAULT 颜色,请使用: Color color = UIManager.getColor
我想更改特定表头的背景颜色。在我的应用程序中,我必须将当前月份的标题颜色设置为红色。 我的代码在这里:: jTable1.getTableHeader(). setDefaultRe
我正在努力使在 Java3D Canvas 上显示 Java Swing 组件并与之交互成为可能。我通过将透明 JPanel 绘制到缓冲图像来显示组件,然后使用 J3DGraphics2D 在 Can
嗨 当我在 swing 中创建按钮时,它会在文本周围添加边框,从而使按钮变大一点。 现在,我确实需要那个屏幕空间,我通常做的是创建一个文本项(禁用),它创建更小的组件大小(文本周围更小的空间)并向其添
有scala.swing.BoxPanel,但它似乎没有捕获重点,因为没有与javax.swing.Box工厂方法createHorizontalStrut等效的东西、createHorizo
我的 scala swing 应用程序中有一个 BoxPanel 按钮,这对我来说很难看,因为按钮的大小各不相同。我已将其更改为 GridPanel,但随后它们也垂直填充了面板,我发现这更难看。我怎样
我刚开始学习 Scala,作为学习过程的一部分,我一直在尝试使用 Swing 编写一些简单的脚本。 这是一个非常精简的例子,它展示了我所看到的问题。 SimpleSwingApp: import sc
我刚刚开始使用 clojure 和跷跷板制作 GUI 应用程序。它只创建一个 JFrame 和几个组件。这是代码。 main 函数除了调用 start-gui 什么也不做并在返回后立即退出。 (ns
Scala 是一种很棒的语言,但不幸的是缺少库文档。如何更改组件的初始大小?我什么都没有(故意),但无论如何都希望它是一定的。我目前有 ... contents = new BoxPanel(Orie
基本设置是这样的:我有一个垂直的 JSplitPane,我希望它有一个固定大小的底部组件和一个调整大小的顶部组件,我通过调用 setResizeWeight(1.0) 来完成。在此应用程序中,有一个按
我是一名优秀的程序员,十分优秀!