gpt4 book ai didi

java - StyledEditorKit 文本对齐无法正常工作

转载 作者:行者123 更新时间:2023-11-30 07:35:48 24 4
gpt4 key购买 nike

我正在尝试在 Java 生成的 html 文档中实现用户可选择的文本对齐方式。我已经尝试过:

JMenuItem leftAlignMenuItem = 
new JMenuItem(new StyledEditorKit.AlignmentAction("Left Align", StyleConstants.ALIGN_LEFT));
JMenuItem centerMenuItem =
new JMenuItem(new StyledEditorKit.AlignmentAction("Center", StyleConstants.ALIGN_CENTER));
JMenuItem rightAlignMenuItem =
new JMenuItem(new StyledEditorKit.AlignmentAction("Right Align", StyleConstants.ALIGN_RIGHT));

以及该主题的各种变体。选择菜单项会使文本在文本 Pane 中正确对齐,并将适当的 html 标记添加到保存的文档中。问题是,添加标签后,单击另一个对齐菜单项不会更改它,因此无法多次更改默认(左)文本对齐方式并保存更改。

我知道我不是第一个遇到此问题的人,但到目前为止我还没有找到任何解决方案,因此我们将不胜感激。

这是我的“M”CVE,不幸的是它仍然很大,但我无法删除更多代码,否则它不会演示问题:

package aligntest;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.JFrame;

public class AlignTest extends JFrame implements ActionListener {

private HTMLDocument doc; // Stores the formatted text.
private JTextPane textPane = new JTextPane(); // The Pane itself.
String FilePath = ""; // Stores the file path.

public AlignTest() { // This method is called automatically when the app is launched.
HTMLEditorKit editorKit = new HTMLEditorKit();
doc = (HTMLDocument)editorKit.createDefaultDocument();
init(); // Calls interface method below.
}

public static void main(String[] args) {
AlignTest editor = new AlignTest();
}
public void init(){

JMenuBar menuBar = new JMenuBar();
getContentPane().add(menuBar, BorderLayout.NORTH);
JMenu fileMenu = new JMenu("File");
JMenu alignMenu = new JMenu("Text Align");

menuBar.add(fileMenu);
menuBar.add(alignMenu);

JMenuItem openItem = new JMenuItem("Open"); //
JMenuItem saveItem = new JMenuItem("Save"); //

openItem.addActionListener(this);
saveItem.addActionListener(this);

fileMenu.add(openItem);
fileMenu.add(saveItem);

JMenuItem leftAlignMenuItem = new JMenuItem(new StyledEditorKit.AlignmentAction("Left Align", StyleConstants.ALIGN_LEFT));
JMenuItem centerMenuItem = new JMenuItem(new StyledEditorKit.AlignmentAction("Center", StyleConstants.ALIGN_CENTER));
JMenuItem rightAlignMenuItem = new JMenuItem(new StyledEditorKit.AlignmentAction("Right Align", StyleConstants.ALIGN_RIGHT));

leftAlignMenuItem.setText("Left");
centerMenuItem.setText("Center");
rightAlignMenuItem.setText("Right");

alignMenu.add(leftAlignMenuItem);
alignMenu.add(centerMenuItem);
alignMenu.add(rightAlignMenuItem);

textPane = new JTextPane(doc); // Create object from doc and set this as value of textPane.
textPane.setContentType("text/html"); // textPane holds html.
JScrollPane scrollPane = new JScrollPane(textPane); // textPane in JScrollPane to allow scrolling if more text than space.
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); // Get screen size to use below.
Dimension scrollPaneSize = new Dimension(1*screenSize.width/2,1*screenSize.height/2); // Together with next line, sets dimensions of textPane relative to screen size.
scrollPane.setPreferredSize(scrollPaneSize);
getContentPane().add(scrollPane, BorderLayout.SOUTH);

pack();
setLocationRelativeTo(null);
show(); // Actually displays the interface.

}

public void actionPerformed(ActionEvent ae) { // Method called with action commands from interface objects above. Which action depends on the text of the interface element.
String actionCommand = ae.getActionCommand();
if (actionCommand.compareTo("Open") == 0){ // Calls method when action command received.
openDocument();
} else if (actionCommand.compareTo("Save") == 0){
saveDocument();
}
}

public void saveDocument(){

String FP = FilePath; // This paragraph calls Save As instead of Save if file not already saved.
String unsaved = "";
int saved = FP.compareTo(unsaved);
if (saved == 0) {
saveDocumentAs();
} else {
save();
}
}

public void saveDocumentAs(){
JFileChooser SaveDialog = new javax.swing.JFileChooser();
int returnVal = SaveDialog.showSaveDialog(this);

if (returnVal == JFileChooser.APPROVE_OPTION) {
java.io.File saved_file = SaveDialog.getSelectedFile();
FilePath = saved_file.toString();

save();
}
}

public void save(){
try {
WriteFile objPane = new WriteFile(FilePath, false);
String PaneText = textPane.getText(); // Gets text from Title Pane.
objPane.writeToFile(PaneText);
}
catch (Exception ex) {
}
}

public void openDocument(){

JFileChooser OpenDialog = new javax.swing.JFileChooser(); // Creates file chooser object.
int returnVal = OpenDialog.showOpenDialog(this); // Defines 'returnVal' according to what user clicks in file chooser.

if (returnVal == JFileChooser.APPROVE_OPTION) { // Returns value depending on whether user clicks 'yes' or 'OK' etc.
java.io.File file = OpenDialog.getSelectedFile(); // Gets path of selected file.
FilePath = file.toString( ); // Converts path of selected file to String.

// The problem seems to be related to the code that starts here...
try {
ReadFile readPane = new ReadFile(FilePath); // Creates "readPane" object from "FilePath" string, using my ReadFile class.
String[] aryPane = readPane.OpenFile(); // Creates string array "aryPane" from "readPane" object.

int i; // Creates integer variable "i".
String PaneText = "";

for (i=0; i < aryPane.length; i++) { // Creates a for loop with starting "i" value of 0, adding 1 to i each time round and ending when i = the number of lines in the aryLines array.
PaneText = PaneText + aryPane[i]; // Add present line to "PaneText".
}
textPane.setText(PaneText); // Displays "PaneText" in "TextPane".

} catch (Exception ex) {
// and ends here. This code also calls ReadFile, so code in that class may be at fault.

}
}
}
}

它还必须调用以下两个类中的方法才能工作:

package aligntest;

import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;

public class ReadFile {

private String path;

public ReadFile(String file_path) {
path = file_path;
}

public String[] OpenFile() throws IOException {

FileReader fr = new FileReader(path);
BufferedReader textReader = new BufferedReader(fr);

int numberOfLines = readLines( );
String[] textData = new String[numberOfLines];

int i;

for (i=0; i < numberOfLines; i++) {
textData[i] = textReader.readLine();
}

textReader.close( );
return textData;
}


int readLines() throws IOException {

FileReader file_to_read = new FileReader(path);
BufferedReader bf = new BufferedReader(file_to_read);

String aLine;
int numberOfLines = 0;

while ((aLine = bf.readLine()) != null) {
numberOfLines++;
}
bf.close();

return numberOfLines;
}

}

&

package aligntest;

import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.IOException;

public class WriteFile {

private String path;
private boolean append_to_file = false;

public WriteFile(String file_path) {
path = file_path;
}

public WriteFile(String file_path, boolean append_value) {
path = file_path;
}

public WriteFile(File SectionPath, boolean success) {
throw new UnsupportedOperationException("Not yet implemented");
}
public void writeToFile( String textLine ) throws IOException {
FileWriter write = new FileWriter(path, append_to_file);
PrintWriter print_line = new PrintWriter(write);

print_line.printf( "%s" + "%n" , textLine);

print_line.close();
}
}

问题似乎与打开文档(第 126 - 138 行)或“ReadFile”类有关:在另一个程序中查看保存的文件时,我可以看到标签正在更改,直到文档关闭,然后使用“AlignTest”再次打开。此后,任何对齐更改都不会反射(reflect)在 html 中。

希望有人能帮忙。

编辑:这是“AlignTest”生成的一些 html。如果将其粘贴到文本文件中,然后在“AlignTest”中打开,它应该会重现该问题:“AlignTest”无法更改对齐标记。

<html>
<head>
<meta id="_moz_html_fragment">

</head>
<body>
<p align="right" style="margin-top: 0pt">
Another
</p>
</body>
</html>

最佳答案

事实证明这比我想象的要困难。让我解释一下幕后发生的事情,然后我将给出一些场景。

AlignmentAction的操作调用文档的 setParagraphAttributesboolean replace设置为false 。在 setParagraphAttributes ,给定属性 ( Alignment.XXX ) 通过 MutableAttributeSet.addAttributes 添加到段落标记的当前属性列表中。效果如下:

  1. 如果段落标签没有任何对齐指令,则 HTML align="xxx"被添加。文件将使用此新属性保存。
  2. 如果段落标记只有 HTML 属性,则会添加内联 CSS 属性:text-align=xxx 。文件仅保存 HTML 属性(CSS 属性被丢弃,我不知道为什么,可能是 " 需要替换为 ' )。
  3. 如果段落标记具有 HTML 和 CSS 属性,则修改 CSS 属性。文件仅保存为 HTML 格式。
  4. 如果段落标记只有 CSS 属性,则会对其进行修改。该文件具有从 CSS 属性转换而来的新 HTML 属性。

总结就是,由于某种原因,无论运行时存在哪些属性,都只能保存 HTML 属性。由于它没有被修改,所以必须先将其删除,然后再添加新属性。可能需要使用不同的编写器。

解决方案的一种尝试是创建您自己的对齐操作并将替换值设置为 true 。问题是它替换了整个段落元素:

<html>
<head>
<meta id="_moz_html_fragment">

</head>
<body>
<body align="center">
Another
</body>
</body>
</html>

您需要做的是访问该元素并“手动”替换属性。创建一个扩展 HTMLDocument 的类和@override它的setParagraphAttributes使其包含行

// attr is the current attribute set of the paragraph element
attr.removeAttribute(HTML.Attribute.ALIGN); // remove the HTML attribute

之前

attr.addAttributes(s); // s is the given attributes containing the Alignment.XXX style.

然后保存文件将按照上述 1-4 种情况保持正确对齐。

最终您将需要使用 HTML 解析器,例如 jsoup ;只是 Google 的 Java HTML 解析器。另请参阅Which HTML Parser is the best?

关于java - StyledEditorKit 文本对齐无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35429725/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com