Text-mouseover popups over a Swing JTextArea?
You can override getToolTipText(Mouse Event event)
as needed.
Addendum: JTextComponent
, the parent of JTextArea
provides location information via two methods: modelToView()
and viewToModel()
. The latter should let you translate the mouse location into a document offset.
Tooltip below caret position in JTextArea
Use modelToView()
method of JTextArea
.
Auto text formatting on JTextArea
JTextArea
does not support styled text. JTextPane
does.
The official tutorial should be a good start: How to Use Editor Panes and Text Panes (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Swing Components)
show letters when mouse move on letters
Use the JTextComponent's viewToModel(Point p)
method to get the location in the document of the text. For example...
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class SetText extends JPanel implements MouseMotionListener {
private static final float POINTS = 40f;
JTextField textField;
private JLabel displayLabel = new JLabel(" ", SwingConstants.CENTER);
public SetText() {
textField = new JTextField("Hello world! How's it going?", 20);
textField.addMouseMotionListener(this);
// make the text bigger so easier to test
textField.setFont(textField.getFont().deriveFont(Font.BOLD, POINTS));
JLabel lbl = new JLabel("Text:");
lbl.setFont(lbl.getFont().deriveFont(Font.BOLD, POINTS));
displayLabel.setFont(displayLabel.getFont().deriveFont(Font.BOLD, POINTS));
JPanel centerPanel = new JPanel();
centerPanel.add(lbl);
centerPanel.add(displayLabel);
setLayout(new BorderLayout());
add(textField, BorderLayout.PAGE_START);
add(centerPanel, BorderLayout.CENTER);
}
public void mouseMoved(MouseEvent e) {
int location = textField.viewToModel(e.getPoint());
String text = textField.getText();
if (text.isEmpty()) {
return;
}
// if (location > 0 && location < text.length()) {
if (location >= 0 && location < text.length()) {
char c = textField.getText().charAt(location);
displayLabel.setText(String.valueOf(c));
} else if (location >= text.length()) {
displayLabel.setText(text.substring(text.length() - 1));
}
}
public void mouseDragged(MouseEvent e) {
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Set Text");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SetText());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
How to get a point value for where a word (or selection) in a JTextArea is on the screen?
You can use a JEditorPane with HTML and add Hyperlinks to any given word. Read the section from the Swing tutorial on How to Use Editor Panes for the basics to get you started.
You can then add a HyperlinkListener
to respond to events when the word is clicked. Read the JEditorPane
API for an example of using a HyperlinkListener
.
For example, when you hover the mouse over anyGivenWord, a tooltip appears,
If you don't want to use Hyperlinks then you could control the tooltip text by overriding the getToolTipText(...)
method. This method receives the MouseEvent so you can get the mouse location. You can then use the viewToModel(...)
method of the JTextArea to get the offset of the mouse into the Document. Then check out the Utilities
. class which will help you get the start/end offsets of the word so you can use the getText(...)
method to extract the word at the current mouse location.
Which event a selection of text trigger in Java JTextArea?
I don't know about any "selection listeners" for text components (although they might be useful), but you could use a CaretListener
to monitor changes to the caret position and check the selection state...
public class TestSelectionMonitor {
public static void main(String[] args) {
new TestSelectionMonitor();
}
public TestSelectionMonitor() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
final JTextArea ta = new JTextArea();
ta.addCaretListener(new CaretListener() {
@Override
public void caretUpdate(CaretEvent e) {
int length = ta.getSelectionEnd() - ta.getSelectionStart();
System.out.println(length);
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(ta));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Select text in 2 JTextarea at the same time
This would be so much easier if JTextComponent
supported a selection model...
Basically, what you can do is attach a ChangeListener
to the JTextArea
's Caret
and monitor for changes to the Caret
, changing the selection of the other JTextArea
in response...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
public class MirrorTextSelection {
public static void main(String[] args) {
new MirrorTextSelection();
}
public MirrorTextSelection() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextArea left;
private JTextArea right;
private DefaultHighlighter.DefaultHighlightPainter highlightPainter;
public TestPane() {
highlightPainter = new DefaultHighlighter.DefaultHighlightPainter(UIManager.getColor("TextArea.selectionBackground"));
left = new JTextArea(20, 20);
left.setWrapStyleWord(true);
left.setLineWrap(true);
right = new JTextArea(20, 20);
right.setWrapStyleWord(true);
right.setLineWrap(true);
left.setText("I am trying to do a small app that compares two similar texts contained in 2 JTextarea. I am wondering if it's possible to select text from the first JTextarea and automatically select the text on the second JTeaxtarea (lets consider that it's guarantee that the 2 JTextarea will have the same text for now) ? Should I share events or listeners ? Thank you");
right.setText("I am trying to do a small app that compares two similar texts contained in 2 JTextarea. I am wondering if it's possible to select text from the first JTextarea and automatically select the text on the second JTeaxtarea (lets consider that it's guarantee that the 2 JTextarea will have the same text for now) ? Should I share events or listeners ? Thank you");
setLayout(new GridLayout(0, 2));
add(new JScrollPane(left));
add(new JScrollPane(right));
left.getCaret().addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int dot = left.getCaret().getDot();
int mark = left.getCaret().getMark();
right.setCaretPosition(mark);
right.moveCaretPosition(dot);
}
});
}
}
}
Now, when you run this, you will find that the right side doesn't seem to get highlighted...what?!
The selection is changing, it's just not been rendered because the component doesn't have focus...
Instead, you could use a Highlighter
to highlight the text...
private DefaultHighlighter.DefaultHighlightPainter highlightPainter;
//...
highlightPainter = new DefaultHighlighter.DefaultHighlightPainter(UIManager.getColor("TextArea.selectionBackground"));
left.getCaret().addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int dot = left.getCaret().getDot();
int mark = left.getCaret().getMark();
right.getHighlighter().removeAllHighlights();
try {
int start = Math.min(dot, mark);
int end = Math.max(dot, mark);
right.getHighlighter().addHighlight(start, end, highlightPainter);
} catch (BadLocationException ex) {
ex.printStackTrace();
}
}
});
Okay, this is now working and you can control the background color of the highlight...
There is another alternative...We can replace the Caret
of the right
JTextArea
with one that doesn't hide the selection when focus is lost...
public class HighlightCaret extends DefaultCaret {
@Override
public void install(JTextComponent c) {
super.install(c);
setSelectionVisible(true);
}
@Override
public void focusGained(FocusEvent e) {
JTextComponent component = getComponent();
if (component.isEnabled()) {
if (component.isEditable()) {
setVisible(true);
}
setSelectionVisible(true);
}
}
@Override
public void focusLost(FocusEvent e) {
setVisible(false);
}
}
Then we set the Caret
to right
...
right.setCaret(nwe HighlightCaret());
This means we don't need the Highlighter
code, we can stick with the original and we get control over not only the background selection color but also the foreground selection color as well...
Related Topics
Drawing in Jlayeredpane Over Exising JPAnels
Spring Boot How to Hide Passwords in Properties File
Barcode Scanner Implementation on Java
How to Validate an Xml File Using Java with an Xsd Having an Include
How to Force Browser to Download File
How to Connect to Postgres Db Due to the Authentication Type 10 Is Not Supported
How to Initialize Hashset Values by Construction
What Exactly Is an Instance in Java
Check If a String Contains a Special Character
Convert Base64 String to Image
How to Display a Svg Byte Array as an Image in a Jasperreport
Why Java.Util.Optional Is Not Serializable, How to Serialize the Object with Such Fields
Jpa/Hibernate Native Queries Do Not Recognize Parameters
Load Resource from Anywhere in Classpath
Difference Between Arrays.Aslist(Array) and New Arraylist<Integer>(Arrays.Aslist(Array))