I am making a small Swing application and have a JTextarea where I want a part of the text to be highlighted.
When I start my appl. the line that I indicated to be highlighted is highlighted by the method "highlight()"
public static void highlight() {
uihw.getTa().setSelectionStart(indexTxt[pencil]);//uihw is the ui instvar that has the jTextarea
uihw.getTa().setSelectionEnd(indexTxt[pencil]+lines[pencil].length());
}
As seen here:
Now, the moment I hit a Button ,it should select the next item below and highlight it.
public static void buttonClicked(String f){
if (pencil!=lines.length-1){
pencil++;
}
highlight();
}
And this is where the highlighting stops working.
I can go through the list up until the end (so I am sure the selection is actually done) but the text isn't highlighted anymore.
Any ideas on the why? Or suggestions for a better implementation of my highlighting feature?
Selections may not be visible if the component loses focus. Instead you can use the Highlighter of the Component:
HighlightPainter highlightPainter = DefaultHighlighter.DefaultHighlightPainter(Color.BLUE);//
Highlighter highlighter = textArea.getHighlighter();
highlighter.addHighlight(start, end, highlightPainter);
If you wish the color to be the same as a selection color, you can use
HighlightPainter highlightPainter = DefaultHighlighter.DefaultPainter;
or specify the selection color via the Look and feel
HighlightPainter highlightPainter = DefaultHighlighter.DefaultHighlightPainter(UIManager.getColor("TextArea.selectionBackground"));
Related
I'm writing a text editor in Java, using Swing. My main component that I use to enter the text is JTextPane. I know how to bold selected text, but I'd also like just to press bold and have new text formatted. Here's my code:
static void boldSelection(JTextPane editor, JButton button){
StyledDocument doc = (StyledDocument) editor.getDocument();
int selectionEnd = editor.getSelectionEnd();
int selectionStart = editor.getSelectionStart();
if (selectionStart == selectionEnd) {
return;
}
Element element = doc.getCharacterElement(selectionStart);
AttributeSet as = element.getAttributes();
MutableAttributeSet asNew = new SimpleAttributeSet(as.copyAttributes());
StyleConstants.setBold(asNew, !StyleConstants.isBold(as));
doc.setCharacterAttributes(selectionStart, editor.getSelectedText().length(), asNew, true);
}
It works, but I have no idea how to change it, since I have to pass the length to setCharacterAttributes.
To be clear:
that's what I have:
Bolding selected text
and that's what I want to do:
Entering bolded text
The EditorKit used by the JTextPane supports a Bold Action along with other common actions the might be used by an editor. So you don't need to write any special code, only create a Swing component to use the Action.
Check out the section from the Swing tutorial on Text Component Features for a working example.
The tutorial example only use menu items but you can also use the Action to create a JButton to add to a JToolBar.
I have this notebook class that I have been working on. I have two problems that I'm facing right now:
1: Bold and Italicize specific text
I have two icons in my toolbar that make the text bolded or italicized when you click on it. All of that works fine, however, It always selects all the text in the document rather than specifically selected text. Is there a way I can use the blue highlight of a left click on a mouse in order to bold or italicize specific text? This is the code for the bolding Abstract Action. The italics looks exactly the same, except for italics.
Action Bold = new AbstractAction("Bold", new ImageIcon("bold.png"))
{
public void actionPerformed(ActionEvent e)
{
if(bolded == false)
{
area.setFont(area.getFont().deriveFont(Font.BOLD));
bolded = true;
}
else
{
area.setFont(area.getFont().deriveFont(Font.PLAIN));
bolded = false;
}
}
};
2 Highlighter over text
I want to add an actual highlighter that will just paint certain groups of words that the user selects yellow. I've read through the Oracle page on this, and I'm still not all that sure about using it. I see a lot of examples of people searching for specific words and highlighting it that way, but I'm not looking to highlight these specific words. I want the user to decide which text to highlight.
Action Highlight = new AbstractAction("Highlight", new ImageIcon("highlighter.png"))
{
public void actionPerformed(ActionEvent e) throws BadLocationException
{
Highlighter highlighter = area.getHighlighter();
HighlightPainter painter = new DefaultHighlighter.DefaultHighlightPainter(Color.RED);
highlighter.addHighlight(0 , 6, painter);
}
};
The code above is what I managed to pull together from some other tutorials online, however, the BadLocationException doesn't compile right when it is inside the Abstract Action, so this isn't looking like a viable option.
Any help is appreciated!
actionPerformed does not throw any checked Exceptions.
Simply remove the exception and catch it inside the method.
public void actionPerformed(ActionEvent e)
{
try {
Highlighter highlighter = area.getHighlighter();
HighlightPainter painter = new DefaultHighlighter.DefaultHighlightPainter(Color.RED);
highlighter.addHighlight(0 , 6, painter);
catch(throws BadLocationException ex) {
ex.printStackTrace();
}
}
}
The SWT Button class has a setForeground(Color) method but it seems to have no effect (the method is actually on Button's superclass). The javadoc says that this method is a hint and may be overridden by the platform. My platform is Windows.
Does this mean that it is not possible to set button foreground color on Windows?
Does it work on other platforms?
Is there a workaround?
On Windows, setForeground for Buttons has no effects.
As a workaround, add a PaintListener to your Button. On this Listener's paintControl method, get the generated event's GC and, with it, re-write the text of your Button using the color you want.
You can, in fact, draw anything over your Button.
If you need Button with style SWT.CHECK you can try use Button without text and add Label element. Example:
chkAutorun = new Button(fCompositeLogin, SWT.CHECK);
Label lblAutorun = new Label(fCompositeLogin, SWT.NONE);
lblAutorun.setForeground(white);
lblAutorun.setText("Autorun");
On windows, setForeground doesn't work for Group either.
If you can convince your users to use the Classic Theme, setForeground will miraculously work.
This is the code to Implement FOreground Color in Buttons in SWT with allowing Mnemonic key to be Shown also and Enabled by Pressing Alt+"Mnemonic Key";
Button radioButton=new Button(parent,SWT.RADIO);
StringBuffer sb = new StringBuffer("I am a Coloured radio button");
String name=null;
String S = "I am a Coloured radio button";
String substr="C";
int i=S.indexOf(substr);
sb.insert(i,"&");
S=sb.toString();
name=sb.substring(i, i+2);
name=sb.toString();
String whiteSpace=" ";
final String TName=S;
for(int l=0;l<1000;l++)
whiteSpace=whiteSpace.concat(" ");
radioButton.setText(name+whiteSpace);
radioButton.addPaintListener(new PaintListener(){
String name=TName;
#Override
public void paintControl(PaintEvent e) {
// TODO Auto-generated method stub
e.gc.setForeground(hex2Col("ffffcc"));
int x=21;
int y=21;
e.gc.drawText(name, x,y,SWT.DRAW_MNEMONIC | SWT.TRANSPARENT);
}
});
Note: hex2Col is my own method to Convert hex Color Code to Color Type
Note: Here ALT+C is Mnemonic Key Combination i have Used
How do I get a JLabel displaying a HTML string to appear greyed out (which is the behaviour of JLabels that don't display HTML text)? Is there another way than actually changing the colour myself by modifying the foreground property?
JLabel label1 = new JLabel("Normal text");
JLabel label2 = new JLabel("<html>HTML <b>text</b>");
// Both labels are now black in colour
label1.setEnabled(false);
label2.setEnabled(false);
// label1 is greyed out, label2 is still black in colour
Thank you very much for all of your responses. From what I gather, it seems that Java doesn't support automatic greying out of JLabels when they use HTML text. Suraj's solution has come closest to the fix considering the limitations.
I have however, tried a different out-of-the box approach, where I have put the HTML text JLabels inside of an inner JPanel and did this:
mInnerPanel.setEnabled(shouldShow); //shouldShow is a boolean value
Which hasn't worked. Any suggestions for this way?
EDIT: Added implemented solution.
If text is HTML, the text wont be grayed out because of the following code in BasicLabelUI#paint()
View v = (View) c.getClientProperty(BasicHTML.propertyKey);
if (v != null) {
v.paint(g, paintTextR);
}
As you can see if the text is html, then the View is used to paint and it is not checked wheter the label is enabled or not.
Hence we need to do it explictly as shown below:
label2.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (!evt.getPropertyName().equals("enabled"))
return;
if (evt.getNewValue().equals(Boolean.FALSE))
label2.setText("<html><font color=gray>HTML <b>text</b></html>");
else
label2.setText("<html><font color=black>HTML <b>text</b></html>");
}
});
Implemented solution:
Color foreground = (shouldShow) ? SystemColor.textText : SystemColor.textInactiveText;
for (Component comp : mInnerPanel.getComponents())
{
comp.setForeground(foreground);
}
Caved in and used setForeground in the end, as it appears that Java seems to explicitly ignore the enabled property when painting JLabels so long as it contains HTML text. See also #Suraj's answer, for "pure" solution.
I would suggest the following, which is combination of two solutions provided here:
public class HtmlLabel extends JLabel{
public void setEnabled(boolean enabled){
if(getClientProperty(BasicHTML.propertyKey) != null ){
Color foreground = (enabled) ? SystemColor.textText : SystemColor.textInactiveText;
setForeground(foreground);
}
super.setEnabled(enabled);
}
}
You can specify the font color in the HTML.
Override the paint method in the UI, set the client property BasicHTML.propertyKey to null if it is disabled and call super...
I'm developing a an eclipse plugin that uses an SWT interface. I need to display text, and within that text there needs to be links. The only two widgets that I've found that will allow me to include clickable links in text are Link and Browser. Browser, however, is overkill for my needs, and I couldn't properly customize the look of it. This only leaves the Link widget.
The problem is I need the Link widget to inherit a gradient from the Composite in which it is in. It does this correctly, only when it is resized or scrolled the Link component flickers. The Link is the only component in which I have seen this effect.
In an attempt to fix this I've tried manipulating other components into having clickable links, but I haven't found a good solution yet.
Is there anyway to fix the flickering effect on the Link, or is there a different component which would support links?
Thanks,
Brian
After spending the day working on this, I came up with a workaround. I created a Composite for the text area. For each word that isn't part of a url,got its own label. For links, each letter got its own label. Then the labels for the url characters got a listener to launch a browser. Using this method provided the Link functionality, handled resizing properly, and has no flicker.
Have you tried passing SWT.NO_BACKGROUND to your Link widget? It might get a little strange... and you may have to do a little more work to get the gui drawing properly, but that would be my first guess.
Other than that, here's my Quick n' dirty implementation of a link inside of a StyledText. You will need to fill in for changing the cursor (if that's something you want), as well as coming up with a good "text to link" mapping scheme.
The only thing is I'm not sure if StyledText will inherit your background... give it a shot.
public class StyledTextExample {
public static void main(String [] args) {
// create the widget's shell
Shell shell = new Shell();
shell.setLayout(new FillLayout());
shell.setSize(200, 100);
Display display = shell.getDisplay();
// create the styled text widget
final StyledText widget = new StyledText(shell, SWT.NONE);
String text = "This is the StyledText widget.";
widget.setText(text);
widget.setEditable(false);
final StyleRange hyperlinkStyle = new StyleRange();
String linkWord = "StyledText";
hyperlinkStyle.start = text.indexOf(linkWord);
hyperlinkStyle.length = linkWord.length();
hyperlinkStyle.fontStyle = SWT.BOLD;
hyperlinkStyle.foreground = display.getSystemColor(SWT.COLOR_BLUE);
widget.setStyleRange(hyperlinkStyle);
widget.addMouseListener(new MouseAdapter() {
public void mouseUp(MouseEvent arg0) {
Point clickPoint = new Point(arg0.x, arg0.y);
try {
int offset = widget.getOffsetAtLocation(clickPoint);
if (widget.getStyleRangeAtOffset(offset) != null) {
System.out.println("link");
}
} catch (IllegalArgumentException e) {
//ignore, clicked out of text range.
}
}});
shell.open();
while (!shell.isDisposed())
if (!display.readAndDispatch()) display.sleep();
}
}