Problem 1: BY using defaulthighlighter, I can make the focused lines change to blue. Now I want to change it to other colors. Do anyone know how to change this param
I think that not accesible to change these methods for all JTextComponents in the case that is there used Highlighter, but is possible to change Foreground only
for example
import java.awt.*;
import javax.swing.*;
import javax.swing.text.DefaultHighlighter;
public class TextAreaLineHightLight {
public static void main(String[] args) throws Exception {
UIManager.put("TextArea.selectionBackground", Color.yellow);
UIManager.put("TextArea.selectionForeground", Color.red);
String string = "Lorem ipsum eum putant gubergren evertitur in, "
+ "no assueverit vituperatoribus eum. Ea cibo offendit vim, est et vivendum qualisque prodesset. "
+ "Vis doctus expetenda contentiones an, no ius mazim epicuri expetendis, "
+ "saperet salutandi forensibus ne usu. Ex fugit alterum usu. "
+ "His ignota cotidieque in, augue erroribus eam no.";
JTextArea textArea = new JTextArea(string);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
JScrollPane textAreaScroll = new JScrollPane(textArea);
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.add(textAreaScroll, BorderLayout.CENTER);
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
String term = "qualisque prodesset. "
+ "Vis doctus expetenda contentiones an, no ius mazim epicuri expetendis";
int termOffset = string.indexOf(term);
Rectangle view = textArea.modelToView(termOffset);
int startOffset = textArea.viewToModel(new Point(0, view.y));
//int rowH = textArea.
int endOffset = textArea.viewToModel(new Point(textArea.getSize().width, view.y));
textArea.getHighlighter().addHighlight(startOffset, endOffset, new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW));
}
}
with the same result for JTextPane
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
public class TextPaneHighlighting extends JFrame {
private static final long serialVersionUID = 1L;
private Highlighter.HighlightPainter cyanPainter;
private Highlighter.HighlightPainter redPainter;
public TextPaneHighlighting() {
UIManager.put("TextPane.selectionBackground", Color.yellow);
UIManager.put("TextPane.selectionForeground", Color.red);
JTextPane textPane = new JTextPane();
textPane.setText("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\n");
JScrollPane scrollPane = new JScrollPane(textPane);
getContentPane().add(scrollPane);// Highlight some text
cyanPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.cyan);
redPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.red);
try {
textPane.getHighlighter().addHighlight(0, 3, DefaultHighlighter.DefaultPainter);
textPane.getHighlighter().addHighlight(8, 14, cyanPainter);
textPane.getHighlighter().addHighlight(19, 24, redPainter);
} catch (BadLocationException ble) {
}
}
public static void main(String[] args) {
TextPaneHighlighting frame = new TextPaneHighlighting();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setSize(300, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
You can achieve this, though not directly, since you have to save the reference to the Highlight
that you had added to the said line, hence you have to traverse through all the Highlights to remove the one you want, have a look at the program attached, might be this will help you to attain what you so desire :
LATEST EDIT : NEW CODE, REMOVED SOME BUGS AND SEEMS LIKE ADDED THE DESIRED FUNCTIONALITY RELATED TO SETTING CARET POSITION
import java.awt.*;
import java.awt.event.*;
import java.util.Map;
import java.util.HashMap;
import javax.swing.*;
import javax.swing.text.*;
public class TextHighlight
{
private JTextArea tarea;
private JComboBox cbox;
private JTextField lineField;
private String[] colourNames = {"RED", "ORANGE", "CYAN"};
private Highlighter.HighlightPainter redPainter;
private Highlighter.HighlightPainter orangePainter;
private Highlighter.HighlightPainter cyanPainter;
private int firstUpdateIndex;
private int counter;
private Map<Integer, Highlighter.Highlight> highlights = new HashMap<Integer, Highlighter.Highlight>();
public TextHighlight()
{
redPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.RED);
orangePainter = new DefaultHighlighter.DefaultHighlightPainter(Color.ORANGE);
cyanPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.CYAN);
firstUpdateIndex = -1;
counter = 0;
}
private void createAndDisplayGUI()
{
final JFrame frame = new JFrame("Text HIGHLIGHT");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5), "Highlighter JTextArea"));
tarea = new JTextArea(10, 10);
JScrollPane scrollPane = new JScrollPane(tarea);
contentPane.add(scrollPane);
JButton remHighButton = new JButton("REMOVE HIGHLIGHT");
remHighButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
String input = JOptionPane.showInputDialog(frame, "Please Enter Start Index : "
, "Highlighting Options : "
, JOptionPane.PLAIN_MESSAGE);
if (input != null && (highlights.size() > 0))
{
int startIndex = Integer.parseInt(input.trim());
Highlighter highlighter = tarea.getHighlighter();
highlighter.removeHighlight(highlights.get(startIndex));
tarea.setCaretPosition(startIndex);
tarea.requestFocusInWindow();
highlights.remove(startIndex);
}
}
});
JButton button = new JButton("HIGHLIGHT TEXT");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
String text = null;
text = tarea.getSelectedText();
if (text != null && text.length() > 0)
{
int startIndex = tarea.getText().indexOf(text);
int endIndex = startIndex + text.length();
Highlighter highlighter = tarea.getHighlighter();
int selection = JOptionPane.showConfirmDialog(
frame, getOptionPanel(), "Highlight Colour : "
, JOptionPane.OK_CANCEL_OPTION
, JOptionPane.PLAIN_MESSAGE);
System.out.println("TEXT : " + text);
System.out.println("START INDEX : " + startIndex);
System.out.println("END INDEX : " + endIndex);
if (selection == JOptionPane.OK_OPTION)
{
String colour = (String) cbox.getSelectedItem();
try
{
if (colour == colourNames[0])
{
System.out.println("Colour Selected : " + colour);
highlighter.addHighlight(startIndex, endIndex, redPainter);
}
else if (colour == colourNames[1])
{
System.out.println("Colour Selected : " + colour);
highlighter.addHighlight(startIndex, endIndex, orangePainter);
}
else if (colour == colourNames[2])
{
System.out.println("Colour Selected : " + colour);
highlighter.addHighlight(startIndex, endIndex, cyanPainter);
}
Highlighter.Highlight[] highlightIndex = highlighter.getHighlights();
System.out.println("Lengh of Highlights used : " + highlightIndex.length);
highlights.put(startIndex, highlightIndex[highlightIndex.length - 1]);
}
catch(BadLocationException ble)
{
ble.printStackTrace();
}
}
else if (selection == JOptionPane.CANCEL_OPTION)
{
System.out.println("CANCEL BUTTON PRESSED.");
}
else if (selection == JOptionPane.CLOSED_OPTION)
{
System.out.println("JOPTIONPANE CLOSED DELIBERATELY.");
}
}
}
});
frame.add(remHighButton, BorderLayout.PAGE_START);
frame.add(contentPane, BorderLayout.CENTER);
frame.add(button, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel getOptionPanel()
{
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(Color.DARK_GRAY, 2), "COLOUR SELECTION"));
panel.setLayout(new GridLayout(0, 2, 5, 5));
JLabel colourLabel = new JLabel("Select One Colour : ");
cbox = new JComboBox(colourNames);
panel.add(colourLabel);
panel.add(cbox);
return panel;
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new TextHighlight().createAndDisplayGUI();
}
});
}
}
OUTPUT :
BEGIN :
HIGHLIGHT FIRST LINE SECOND
REMOVED HIGHLIGHT
HIGHLIGHTING THE SAME LINE WITH DIFFERENT COLOUR
LATEST EDIT in lines with the SAMPLE CODE in the QUESTION
import java.awt.*;
import java.net.MalformedURLException;
import javax.swing.*;
import javax.swing.text.*;
public class Test {
public static void main(final String[] args) throws MalformedURLException {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
init();
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
private static void init() throws BadLocationException {
JFrame frame = new JFrame();
final JTextArea textArea = new JTextArea();
JScrollPane pane = new JScrollPane(textArea);
textArea.setText("Something. Something else.\nA second line\na third line"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Samething else.\nA second line\na third line"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sbmething else.\nA second line\na third line"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Scmething else.\nA second line\na third line"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sdmething else.\nA second line\na third line"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Semething else.\nA second line\na third line"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sfmething else.\nA second line\na third line"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sgmething else.\nA second line\na third line"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n");
textArea.setSelectionColor(Color.RED);
frame.add(pane);
frame.setSize(300, 120);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
String turnToString2 = "Sdmething else.\nA second line\na third line"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla";
int pos2 = textArea.getText().indexOf(turnToString2);
Rectangle startIndex = textArea.modelToView(pos2);
textArea.getHighlighter().addHighlight(pos2,
pos2 + turnToString2.length(),
new DefaultHighlighter.DefaultHighlightPainter(Color.yellow));
int y = startIndex.y + (pane.getHeight() - 10);
System.out.println("Pane Height : " + pane.getHeight());
System.out.println("X : " + startIndex.x);
System.out.println("Y : " + y);
System.out.println("Y (pos2) : " + startIndex.y);
textArea.setCaretPosition(textArea.viewToModel(new Point(startIndex.x, y)));
pane.scrollRectToVisible(new Rectangle(startIndex.x, y));
}
}
Here is the OUTPUT :
To set the selection background color, use setSelectionColor (illustrated below but not used).
I don't really understand what you're saying with it always appears at the bottom of the window. I want to have it at the top but I am guessing (and I may be wrong here) that your textarea is in a scrollpane and that by highlighting the text it scrolls to the end of your selection, so I suggest to set the caret position after highlighting the text.
Here is a sample of what I understood. Let me know if this is not what you're looking for:
import java.awt.Color;
import java.net.MalformedURLException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
public class Test {
public static void main(final String[] args) throws MalformedURLException {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
init();
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
private static void init() throws BadLocationException {
JFrame frame = new JFrame();
final JTextArea textArea = new JTextArea();
JScrollPane pane = new JScrollPane(textArea);
textArea.setText("Something. Something else.\nA second line\na third line"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n");
textArea.setSelectionColor(Color.RED);
frame.add(pane);
frame.setSize(300, 120);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
String turnToString = "Something else.\nA second line\na third line"
+ "Blabla\nBlabla\nBlabla\nBlabla\nBlabla";
final int pos = textArea.getText().indexOf(turnToString);
textArea.getHighlighter().addHighlight(pos,
pos + turnToString.length(),
new DefaultHighlighter.DefaultHighlightPainter(Color.yellow));
textArea.scrollRectToVisible(new Rectangle(0, 0, pane.getViewport().getWidth(), pane.getViewport().getHeight()));
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
textArea.setCaretPosition(pos);
}
});
}
}
To solve 2) Use modelToView to get point of the first selected row. Then use scrollRectToVisible using the Point (NOTE: height of the rectangle must be your viewport height).