我正在开发一个 Java 应用程序,除其他外,它应该在文本字段中显示 Magic: The Gathering 卡的详细信息(因为我使用的是 Swing,所以当前是一个JTextPane)。
这些细节包含文本和小图标,其中一些图标与文本内嵌(因此文本围绕它们流动),而根据我的设计,一些图标与同一行中的一些左对齐文本右对齐。
我从另一个应用程序中获取了一张图像,该应用程序的设计与我正在开发的应用程序非常相似(尽管不是使用 Java):
它基本上应该是这样的。
现在,出于对一切的热爱,我无法让它在JTextPane.
我开始尝试使用 CSS 来做到这一点,但发现JEditorPane和 子类不支持“float”属性,所以我尝试使用 PaneStyledDocument来代替。
我一开始没有让第一部分工作(顶部的图标和右对齐文本总是忽略它们的对齐方式,并直接放置在行中左对齐文本之后),直到我发现这个问题。
建议使用以下代码行:
pane.setEditorKit(new HTMLEditorKit());
Run Code Online (Sandbox Code Playgroud)
这确实解决了我的第一个问题。
但现在我陷入了第二部分,使第二部分中的这些图标与文本内联。这是我目前得到的:
我发现,出于某种原因,当您JTextPane使用带有上面代码行的编辑器套件切换到 html 模式时,插入组件会变得完全疯狂。
顶部的图标(实际上我已将其合并为单个图像)和下面文本中的图标(未合并)都位于 的内部JLabels,但如果我将它们添加为图像或添加到 的内部并不重要JLabels。图像或标签绝对不会比你在那里看到的大,我根本不知道额外的空白来自哪里。
我发现了这个问题,答案表明这是某种错误,或者只是 .html 模式的奇怪行为JEditorPane。
如果我再次删除上面的代码行,我最终会遇到原来的问题:
根据图标在文本中的具体位置,我会得到各种不同的奇怪结果。我在下面整理了更多示例图片:
那么,我该如何解决这个问题呢?除了这部分之外,这JTextPane对我来说工作得很好,但我可能会使用其他解决方案,只要最终结果看起来仍然相同。请记住,我可能想在其中添加一些其他组件(如 Button),因此如果可能的话,我想坚持使用 Swing 原生的组件。
用户将无法编辑 TextPane 的内容,但我想稍后添加一个选项,以便一键复制所有内容(所以我宁愿保留文本区域)。
下面,我整理了一个(不是那么简单的)工作示例供您使用:
(编辑:现在更新了底部的代码!旧代码仍然存在于以下链接下。)
我正在使用的图标如下。您需要重命名它们并更改代码中的路径。
需要注意的一些事项:
在 Sharcoux 的回答之后,我编辑了代码,在实际的 JTextPane 上方有 …
我有以下"树"的对象:
JPanel
JScrollPane
JPanel
JPanel
JScrollPane
JTextPane
Run Code Online (Sandbox Code Playgroud)
当使用鼠标滚轮滚动外部JScrollPane我遇到一个恼人的问题.一旦鼠标光标触及内部JScrollPane,似乎滚动事件就会传递到JScrollPane中,并且第一个不再处理.这意味着滚动"父"JScrollPane停止.
是否可以仅禁用内部JScrollPane上的鼠标滚轮?或者更好的是,如果没有要滚动的内容(大多数情况下textpane只包含1-3行文本),则禁用滚动,但如果有更多内容则启用它?
我有一个JTextPane通过从文件读取填充,之后数据被解析和格式化.不允许用户编辑JTextPane,但我希望他们能够使用可见光标在其中导航.
如果我使用setEditable(false),光标是不可见的,虽然可以通过按住Shift并使用箭头键选择文本块来间接观察不可见光标的位置.
要启用一个可见光标同时禁止编辑,而不是setEditable(false)我创建了一个虚拟的DocumentFilter,根本无助于它的insertString(),remove()和replace()方法.但是我必须交换常规过滤器以便以编程方式填充JTextPane文件,然后在将控制返回给用户之前放回虚拟过滤器.
到目前为止,这似乎有效,但是有一个更简单的解决方案吗?如果我保留原样,是否有任何按键或鼠标活动序列可以某种方式允许用户编辑文本窗格,因为它在技术上可编辑setEditable?
目前它看起来如此

怎么做它看起来如此?

以下是我的代码:
JFrame f = new JFrame();
JTextPane textPane = new JTextPane();
JTextField component = new JTextField(" ");
component.setMaximumSize(component.getPreferredSize());
textPane.setSelectionStart(textPane.getDocument().getLength());
textPane.setSelectionEnd(textPane.getDocument().getLength());
textPane.insertComponent(component);
try {
textPane.getDocument().insertString(textPane.getDocument().getLength(), "text",
new SimpleAttributeSet());
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
f.add(new JScrollPane(textPane));
f.setSize(200, 100);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
Run Code Online (Sandbox Code Playgroud)
我发现接近这个主题的单个问题:JTextPane插入组件,错误的垂直对齐 但是如何更改对齐没有答案.但根据那里的讨论,它必须是可能的.
所以,我有一种情况,滚动条需要在遇到某种逻辑情况时自动滚动.
在我的情况下,我写了几行JTextPane,并且我突出显示单词.因此,当到达该点时,文本不可见,滚动条应自动向下滚动.
很少有屏幕截图可以说清楚:

正如您所看到的,现在屏幕上充满了高位文本.所以此时滚动条应向下移动,如下所示:

我是空白,使用的逻辑是:
1).txt 文件行数将改变.
2)突出显示单词的时间可能会改变.
有什么逻辑可以克服这种情况?
我是Java的新手,我刚刚在StackOverflow中找到了这段代码:ResizeTextArea.
我想用JTextPane而不是JTextArea.在JTextPane,没有setRows()方法可以改变行数.任何帮助,将不胜感激.
正如问题所述,我如何成功地将多个图标放在同一行文本中JTextPane?每当我尝试改变其值时actionText,结果都是非常不可预测的.举个例子,这就是我想要实现的目标:

如果我只传递图标标记来创建图标(例如""),它们只是叠加在一起(或者可能不是,很难说).如果我输入","或"和",则第一个战斗机图标出现在第一行,而逗号和其他战斗机图标出现在第二行.
我目前正在尝试使用基于oracle教程构建的解决方案JTextPane:JTextPane教程.以下是我创建自定义文本窗格的代码块.
public final class GameTextPaneFactory {
private static final String[] ADVENTURER_TOKENS = {"<FIGHTER>", "<CLERIC>", "<WIZARD>", "<ROGUE>"};
private static final int TEXT_PANE_WIDTH = 30;
public static JTextPane createActionTextPane(String actionText) {
ArrayList<String>[] wordsAndStyles = parseActionText(actionText);
JTextPane actionTextPane = new JTextPane();
StyledDocument doc = actionTextPane.getStyledDocument();
addStylesToDocument(doc);
try {
for (int i=0; i < wordsAndStyles[0].size(); i++) {
doc.insertString(doc.getLength(), wordsAndStyles[0].get(i),
doc.getStyle(wordsAndStyles[1].get(i)));
}
} catch (BadLocationException ble) {
System.err.println("Couldn't insert initial text into text pane.");
} …Run Code Online (Sandbox Code Playgroud) 我正在使用一个JTextPane对象,假设它的名字是jtp,所以我可以用斜体或粗体显示一些有点短的String .我有一个字符串,我们将其命名为具有换行符的otxt.鉴于我使用的是Windows,它意味着\ r \n并使用它创建
System.getProperty("line.separator")
Run Code Online (Sandbox Code Playgroud)
并且在它们完全形成之前消除所有疑虑,我将我的String转换为char数组,走过char数组并在Eclipse控制台中编写所有字符的代码,使用隐式转换通过强制转换为int,是的,只有一个代码13 ,代表\ r和只有一个代码10,代表\n.现在,如果我使用
jtp.setText(otxt);
Run Code Online (Sandbox Code Playgroud)
一切都很顺利 - 我从中转换为char数组
jtp.getText()
Run Code Online (Sandbox Code Playgroud)
并打印出所有字符的代码,我只有一个代码13(\ r)和一个代码10(\n),因为我应该有.但我需要用斜体或粗体显示otxt的某些部分,所以我必须使用
jtp.insertString(0 /*offset*/, otxt, attributeSet /*italic, bold or whatever stylistic property*/)
Run Code Online (Sandbox Code Playgroud)
这是一个大问题:这会创建\ r \n \n \n \n我应该有\ r \n.这是使用相同的过程确认的:1)从jtp.getText()到char数组的字符串; 2)走阵; 3)打印字符代码; 我看到代码13(\ r)两次和代码10(\n)一次.帮我解决这个问题.希望你能找到有趣的问题.
java ×10
jtextpane ×10
swing ×10
jscrollpane ×2
alignment ×1
automation ×1
icons ×1
image ×1
jcomponent ×1
jtextarea ×1
newline ×1