example - jtextpane java netbeans
¿Cómo puedo configurar cada personaje con un color/color de fondo diferente en un JTextPane? (3)
He estado buscando esto por un tiempo y hasta ahora todo lo que he podido encontrar es cómo crear un estilo y aplicarlo a un personaje como ese:
StyledDocument doc = (StyledDocument) new DefaultStyledDocument();
JTextPane textpane = new JTextPane(doc);
textpane.setText("Test");
javax.swing.text.Style style = textpane.addStyle("Red", null);
StyleConstants.setForeground(style, Color.RED);
doc.setCharacterAttributes(0, 1, textpane.getStyle("Red"), true);
Esto es útil si solo tiene algunos estilos en su documento y desea almacenarlos por nombre para que pueda aplicarlos fácilmente más adelante. En mi aplicación, quiero poder establecer el color frontal (uno de los pocos valores) y el color de fondo (escala de grises, muchos valores diferentes) de forma independiente para cada personaje en el texto. Parece una gran pérdida crear potencialmente cientos / miles de estilos diferentes para esto. ¿Hay alguna manera de establecer estos atributos sin tener que crear un nuevo estilo cada vez? Sería mucho más fácil si solo tuviera que renderizar el texto, pero también necesito hacerlo editable. ¿Hay alguna manera de hacer esto con JTextPane
, o hay otra clase de swing que ofrece esta funcionalidad?
Creo que la mejor forma de hacerlo es como tenemos en los editores destacados, sin perseguir personajes, pero que tienen un patrón, por ejemplo:
private static HashMap<Pattern, Color> patternColors;
private static String GENERIC_XML_NAME = "[A-Za-z]+[A-Za-z0-9//-_]*(:[A-Za-z]+[A-Za-z0-9//-_]+)?";
private static String TAG_PATTERN = "(</?" + GENERIC_XML_NAME + ")";
private static String TAG_END_PATTERN = "(>|/>)";
private static String TAG_ATTRIBUTE_PATTERN = "(" + GENERIC_XML_NAME + ")//w*//=";
private static String TAG_ATTRIBUTE_VALUE = "//w*//=//w*(/"[^/"]*/")";
private static String TAG_COMMENT = "(<//!--[//w ]*-->)";
private static String TAG_CDATA = "(<//!//[CDATA//[.*//]//]>)";
private static final Color COLOR_OCEAN_GREEN = new Color(63, 127, 127);
private static final Color COLOR_WEB_BLUE = new Color(0, 166, 255);
private static final Color COLOR_PINK = new Color(127, 0, 127);
static {
// NOTE: the order is important!
patternColors = new LinkedHashMap<Pattern, Color>();
patternColors.put(Pattern.compile(TAG_PATTERN), Color.BLUE); // COLOR_OCEAN_GREEN | Color.BLUE
patternColors.put(Pattern.compile(TAG_CDATA), COLOR_WEB_BLUE);
patternColors.put(Pattern.compile(TAG_ATTRIBUTE_PATTERN), COLOR_PINK);
patternColors.put(Pattern.compile(TAG_END_PATTERN), COLOR_OCEAN_GREEN);
patternColors.put(Pattern.compile(TAG_COMMENT), Color.GRAY);
patternColors.put(Pattern.compile(TAG_ATTRIBUTE_VALUE), COLOR_OCEAN_GREEN); //Color.BLUE | COLOR_OCEAN_GREEN
}
public XmlView(Element element) {
super(element);
// Set tabsize to 4 (instead of the default 8).
getDocument().putProperty(PlainDocument.tabSizeAttribute, 4);
}
No estoy seguro de lo que quieres decir, pero no puedes recorrer cada personaje en el JtextPane
y dentro de ese ciclo iterar a través de todas las letras / caracteres que deseas resaltar, etc. Tener una instrucción if que verifique el carácter y luego establecer el Style
consecuencia.
Aquí hay un ejemplo que hice. Lo implementé solo para los caracteres hyw para propósitos de demostración:
//necessary imports
import java.awt.Color;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class Test {
/**
* Default constructor for Test.class
*/
public Test() {
initComponents();
}
public static void main(String[] args) {
/**
* Create GUI and components on Event-Dispatch-Thread
*/
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Test test = new Test();
}
});
}
/**
* Initialize GUI and components (including ActionListeners etc)
*/
private void initComponents() {
JFrame jFrame = new JFrame();
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
StyledDocument doc = (StyledDocument) new DefaultStyledDocument();
JTextPane textPane = new JTextPane(doc);
textPane.setText("Hello, world! :)");
//create necessary styles for various characters
javax.swing.text.Style style = textPane.addStyle("Red", null);
StyleConstants.setForeground(style, Color.RED);
javax.swing.text.Style style2 = textPane.addStyle("Blue", null);
StyleConstants.setForeground(style2, Color.BLUE);
//create array of characters to check for and style
String[] lettersToEdit = new String[]{"h", "w"};
//create arraylist to hold each character in textPane
ArrayList<String> strings = new ArrayList<>();
//get all text
String text = textPane.getText();
//populate arraylist
for (int i = 0; i < text.length(); i++) {
strings.add(text.charAt(i) + "");
}
//declare variabe to hold position
int position = 0;
for (String s1 : strings) {//for each character in the textpane text
for (String s2 : lettersToEdit) {//for each character in array to check (lettersToEdit)
if (s2.toLowerCase().equalsIgnoreCase(s1)) {//if there was a match
System.out.println("found a match: " + s1);
System.out.println("counter: " + position + "/" + (position + 1));
//check which chacacter we matched
if (s1.equalsIgnoreCase(lettersToEdit[0])) {
//set appropriate style
doc.setCharacterAttributes(position, 1, textPane.getStyle("Red"), true);
}
if (s1.equalsIgnoreCase(lettersToEdit[1])) {
doc.setCharacterAttributes(position, 1, textPane.getStyle("Blue"), true);
}
}
}
//increase position after each character on textPane is parsed
position++;
}
jFrame.add(textPane);
//pack frame (size JFrame to match preferred sizes of added components and set visible
jFrame.pack();
jFrame.setVisible(true);
}
}
Si desea cambiar el estilo de cada personaje en un panel de texto, aquí hay una forma completamente aleatoria de hacerlo. Usted crea un conjunto de atributos diferente para cada personaje. Depende de usted para encontrar la combinación adecuada (contraste en primer plano / fondo, no demasiada diferencia en el tamaño de los caracteres, etc.). También podría almacenar los diferentes estilos que ya ha aplicado para que no use el mismo dos veces.
import java.awt.Color;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class TestDifferentStyles {
private void initUI() {
JFrame frame = new JFrame(TestDifferentStyles.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
StyledDocument doc = new DefaultStyledDocument();
JTextPane textPane = new JTextPane(doc);
textPane.setText("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has "
+ "been the industry''s standard dummy text ever since the 1500s, when an unknown printer took a galley of "
+ "type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the "
+ "leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the"
+ " release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing "
+ "software like Aldus PageMaker including versions of Lorem Ipsum.");
Random random = new Random();
for (int i = 0; i < textPane.getDocument().getLength(); i++) {
SimpleAttributeSet set = new SimpleAttributeSet();
// StyleConstants.setBackground(set, new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)));
StyleConstants.setForeground(set, new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)));
StyleConstants.setFontSize(set, random.nextInt(12) + 12);
StyleConstants.setBold(set, random.nextBoolean());
StyleConstants.setItalic(set, random.nextBoolean());
StyleConstants.setUnderline(set, random.nextBoolean());
doc.setCharacterAttributes(i, 1, set, true);
}
frame.add(new JScrollPane(textPane));
frame.setSize(500, 400);
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestDifferentStyles().initUI();
}
});
}
}