Reputation: 2434
Why the text in JTextPane cannot be selected programmatically if there is a JTextField present? Has something to do with focus i think. Thx.
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.beans.PropertyChangeListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;
public class align extends JFrame {
private align() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addPane(this, "one");
pack();
setVisible(true);
}
public static void main(String[] args) {
align t = new align();
}
private void addPane(JFrame frame, String name) {
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.LEFT));
// if the next line is disabled, then the text is JTextPane is correctly highlighted.,,
panel.add(makeField("line1"));
JTextPane p = new JTextPane();
p.setText("abcdef");
p.setSelectionStart(2);
p.setSelectionEnd(4);
p.setFocusable(true);
p.requestFocus();
p.requestDefaultFocus();
panel.add(p);
frame.getContentPane().add(panel);
}
private JComponent makeField(String name) {
JTextField textArea = new JTextField();
textArea.setText(name);
textArea.setEditable(false);
return textArea;
}
}
EDIT:
Got it to display the selected text by firing the key event after the frame has been built. A better (longer) solution would be to have a read-only TextPane with custom Highlighter and DocumentListener that keeps the clipboard updated on Ctrl-C.
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(
new KeyEvent(textPane, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, KeyEvent.VK_TAB));
Upvotes: 1
Views: 2036
Reputation: 51535
Just for fun (after all, it's Friday :-) I followed up Stanislav's comment, extending DefaultCaret to keep the selection visible for unfocused textComponents.
The basic ideas
fool super into believing that the selection is always visible
public static class WrappingCaret extends DefaultCaret {
private DefaultCaret delegate;
private HighlightPainter focusedSelectionPainter;
private HighlightPainter unfocusedSelectionPainter;
private boolean focusedSelectionVisible;
public WrappingCaret(JTextComponent target) {
installDelegate((DefaultCaret) target.getCaret());
target.setCaret(this);
}
private void installDelegate(DefaultCaret delegate) {
this.delegate = delegate;
setBlinkRate(delegate.getBlinkRate());
}
private void installSelectionPainters() {
if (delegate instanceof BasicCaret) {
installDefaultPainters();
} else {
try {
Method method = delegate.getClass().getDeclaredMethod(
"getSelectionPainter");
method.setAccessible(true);
focusedSelectionPainter = (HighlightPainter) method
.invoke(delegate);
Constructor<?>[] constructors = focusedSelectionPainter
.getClass().getDeclaredConstructors();
constructors[0].setAccessible(true);
unfocusedSelectionPainter = (HighlightPainter) constructors[0]
.newInstance(getUnfocusedSelectionColor());
} catch (Exception e) {
installDefaultPainters();
}
}
}
private Color getUnfocusedSelectionColor() {
Color first = getComponent().getSelectionColor();
// create a reasonable unfocusedSelectionColor
return PaintUtils.setAlpha(first, 125);
}
private void installDefaultPainters() {
focusedSelectionPainter = super.getSelectionPainter();
unfocusedSelectionPainter = new DefaultHighlightPainter(
getUnfocusedSelectionColor());
}
/**
* @inherited <p>
*/
@Override
public void install(JTextComponent c) {
super.install(c);
installSelectionPainters();
setSelectionVisible(isSelectionVisible());
}
/**
* @inherited <p>
*/
@Override
public void setSelectionVisible(boolean vis) {
focusedSelectionVisible = vis;
super.setSelectionVisible(!isSelectionVisible());
super.setSelectionVisible(true);
}
/**
* @inherited <p>
*/
@Override
protected HighlightPainter getSelectionPainter() {
return focusedSelectionVisible ? focusedSelectionPainter
: unfocusedSelectionPainter;
}
}
Enjoy!
Upvotes: 4
Reputation: 168845
The text in the JTextPane
is selected. The trouble is that it does not give any visual indication unless the component is focused. Try tabbing to the component once the GUI is shown.
so, i should release note this?
No, you should redesign your broken GUI that uses text selection to identify text of interest. Text selection is more something for the end user to do, not the application.
Given JTextPane
is a component that supports formatting, possibly make the text bold or italic for instance.
Upvotes: 3
Reputation: 324197
Maybe you should be using a Highlighter so the highlighting appears in all text components:
Highlighter.HighlightPainter yellow =
new DefaultHighlighter.DefaultHighlightPainter( Color.YELLOW );
try
{
textPane.getHighlighter().addHighlight(2, 4, yellow);
}
catch(BadLocationException ble) { System.out.println(ble); }
Upvotes: 3