Highlighter addHighlight not changing text color - java

I have a JTextArea in which I highlight some text using the addHighlight method of the Highlighter I get from the JTextArea. It highlights the text but it does not change the text color of the highlighted text to the selectedTextColor I have set.
Here is an example:
import java.awt.Color;
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;
import javax.swing.text.Highlighter;
import javax.swing.text.Highlighter.HighlightPainter;
public class SSCCE {
private JFrame frame;
private JTextArea textArea;
public SSCCE() {
frame = new JFrame();
frame.setTitle("Huge Text");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
textArea = new JTextArea("abcd abcd abcd");
textArea.setBackground(Color.DARK_GRAY);
textArea.setForeground(Color.LIGHT_GRAY);
textArea.setSelectionColor(Color.LIGHT_GRAY);
textArea.setSelectedTextColor(Color.DARK_GRAY);
Highlighter highLighter = textArea.getHighlighter();
HighlightPainter highLightPainter = new DefaultHighlighter.DefaultHighlightPainter(textArea.getSelectionColor());
try {
highLighter.addHighlight(0, 10, highLightPainter);
} catch (BadLocationException e) {
e.printStackTrace();
}
frame.add(new JScrollPane(textArea));
frame.setSize(400, 350);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SSCCE();
}
});
}
}

Worth reading about Using Text Components
If you intend to use an unstyled text component then choose text field, password field, formatted text field, or text area.
If you intend to use a styled text component, see How to Use Editor Panes and Text Panes
JTextArea doesn't support this functionality to style a sub set of the entire content. It applies styles but across the entire content.
Find a sample code here change specific text color in java

Related

Java swing jtextarea on a tab does not fill out the tab, cannot get it to fill even with scrollbar added

So I'm using the Oracle tabbed example to create a Java swing application to help retrieve quick data from an internal database for a very small company and I'm very new at Java (decent scripting, though). My problem is that retrieved data from the database goes outside tab boundariesenter image description here. From reading a question, I learned I should use a textarea, so I modified to use a text area but then I could not scroll. I fixed the scroll, but now the data is just in a small window on the tab. I can enlarge the tab, I have my scrolls, but I cannot fill out the text area.
This is the gridlayout from the documentation example:
super(new GridLayout(8, 40));
This is the pane that displays the information where inv is an array list defined as follows:
ArrayList<String> inv = new ArrayList<String>();
The data is pulled into the pane with the following code (note that the dimension does not change the text area, in fact, I do not believe this has any effect on the code at all so it is commented out during my testing:
JComponent panel2 = makeTextPanel(inv.toString());
//panel2.setPreferredSize(new Dimension(100, 50));
tabbedPane.addTab("Customers", null, panel2,
"Displays Customer Details");
tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
} catch (SQLException sqlException) {
System.out.println(sqlException);
}
This is the code for the panel using scroll tab, text area, etc. which is a modified version of the copied code:
//Add the tabbed pane to this panel.
add(tabbedPane);
//The following line enables to use scrolling tabs.
tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
}
protected JComponent makeTextPanel(String text) {
JPanel panel = new JPanel(false);
JTextArea filler = new JTextArea(text, 100, 50);
JScrollPane scroll = new JScrollPane (filler,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
//filler.setHorizontalAlignment(JTextArea.CENTER);
panel.setLayout(new GridLayout(1, 1));
//panel.add(filler);
panel.add(scroll);
return panel;
}
The tabbed pane is then displayed using the original code which I did not make any changes:
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("TabbedPane");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Add content to the window.
frame.add(new TabbedPane(), BorderLayout.CENTER);
//Display the window.
frame.pack();
frame.setVisible(true);
}
The question is, how can I get the text area to fill out the pane instead of just being 1/4 the size (regardless of how I resize the window either in the code or the GUI? The documentation doesn't seem to offer me much (based on searches) that work as I am already setting the scrollbar in the textarea like the documentation specifies. I tried setLineWrap(true) like another question but that was of no help either. See the image for an example of the issue I'm having. Any thoughts?
I'd use a BorderLayout to control the layout of the JScrollPane so it can automatically fill the available space.
You can control the JTextArea's visible size via it's rows and columns properties
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
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.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
// Replace this with your text retrieval process
List<String> text = new ArrayList<String>(128);
try (BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/resources/StarWarANewHope.txt")))) {
String line = null;
while ((line = br.readLine()) != null) {
text.add(line);
}
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
// Use this to format the results for the text area
StringJoiner joiner = new StringJoiner("\n");
for (String line : text) {
joiner.add(line);
}
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("Customers", null, new TestPane(joiner.toString()), "Displays customer details");
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(tabbedPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane(String text) {
JTextArea filler = new JTextArea(text, 25, 25);
filler.setWrapStyleWord(true);
filler.setLineWrap(true);
JScrollPane scroll = new JScrollPane(filler);
//filler.setHorizontalAlignment(JTextArea.CENTER);
setLayout(new BorderLayout());
//panel.add(filler);
add(scroll);
}
}
}
If you continue to have issues, consider providing a minimal reproducible example, it takes out the guess work and generally results in better answers for more details

How to set bold font style for selected text in JTextArea instance

I want to set bold font style for selected text in JTextArea instance.
I tried this way:
textArea.getSelectedText().setFont(new Font("sansserif",Font.BOLD, 12));
But it does not work. Also I've tried JTextPane and JEditorPane instead of JTextArea but without effect.
How can I do that?
I want to set bold font style for selected text in JTextArea instance.
You can't do this for a JTextArea. You need to use a JTextPane.
Then you can use the default Action provided by the StyledEditorKit. Create a JButton or JMenuItem to do this:
JButton boldButton = new JButton( new StyledEditorKit.BoldAction() );
JMenuItem boldMenuItem = new JMenuItem( new StyledEditorKit.BoldAction() );
Add the button or menu item to the frame. Then the use can click on the button/menu item to bold the text after it has been selected. This is the way most editor work. You can also add an acceleration to the Action to the Action can be invoked just by using the keyboard.
Read the section from the Swing tutorial on Text Component Features for more information and a working example.
Introduction
The (useful) answers for how to do what you want to do have already been posted by #Freek de Bruijn and #Gilbert Le Blanc, but none of them explain why what you're trying to do doesn't work. This isn't an answer for
How can I do that?
but an explanation for
But it does not work.
Edit: #camickr posted what I believe is the correct approach.
Answer
From the tutorial about about JTextArea:
You can customize text areas in several ways. For example, although a given text area can display text in only one font and color, you can set which font and color it uses.
(all emphasis in quotes are mine) and
If you want the text area to display its text using multiple fonts or other styles, you should use an editor pane or text pane.
This is because JTextArea uses PlainDocument (see this):
PlainDocument provides a basic container for text where all the text is displayed in the same font.
However, a JTextPane uses DefaultStyledDocument:
a container for styled text in no particular format.
You have to set up a caret listener on a JTextPane to listen for when some or all of the text is selected.
Here's the GUI I created.
And here's the code:
package com.ggl.testing;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
public class JTextPaneTest implements Runnable {
private JTextPane textPane;
private StyledDocument styledDocument;
public static void main(String[] args) throws BadLocationException {
SwingUtilities.invokeLater(new JTextPaneTest());
}
public JTextPaneTest() throws BadLocationException {
this.styledDocument = new DefaultStyledDocument();
this.styledDocument.insertString(0, displayText(), null);
addStylesToDocument(styledDocument);
}
#Override
public void run() {
JFrame frame = new JFrame("JTextPane Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
textPane = new JTextPane(styledDocument);
textPane.addCaretListener(new SelectedText());
textPane.setPreferredSize(new Dimension(250, 125));
JScrollPane scrollPane = new JScrollPane(textPane);
frame.add(scrollPane);
frame.pack();
frame.setVisible(true);
}
private String displayText() {
return "This is some sample text. Pick part of the text to select "
+ "by double clicking on a word.";
}
private void addStylesToDocument(StyledDocument styledDocument) {
Style def = StyleContext.getDefaultStyleContext().getStyle(
StyleContext.DEFAULT_STYLE);
Style s = styledDocument.addStyle("bold", def);
StyleConstants.setBold(s, true);
}
private class SelectedText implements CaretListener {
#Override
public void caretUpdate(CaretEvent event) {
int dot = event.getDot();
int mark = event.getMark();
if (dot != mark) {
if (dot < mark) {
int temp = dot;
dot = mark;
mark = temp;
}
boldSelectedText(mark, dot);
}
}
private void boldSelectedText(int mark, int dot) {
try {
int length = dot - mark;
String s = styledDocument.getText(mark, length);
styledDocument.remove(mark, length);
styledDocument.insertString(mark, s,
styledDocument.getStyle("bold"));
} catch (BadLocationException e) {
e.printStackTrace();
}
}
}
}
You could use a JTextPane component similar to changing the color as described in the following answer: How to set font color for selected text in jTextArea.
For example:
import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.WindowConstants;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
public class BoldSelected {
public static void main(final String[] args) {
new BoldSelected().launchGui();
}
private void launchGui() {
final String title = "Set bold font style for selected text in JTextArea instance";
final JFrame frame = new JFrame("Stack Overflow: " + title);
frame.setBounds(100, 100, 800, 600);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
final JTextPane textPane = new JTextPane();
textPane.setText(title + ".");
final Style style = textPane.addStyle("Bold", null);
StyleConstants.setBold(style, true);
textPane.getStyledDocument().setCharacterAttributes(4, 33, style, false);
frame.getContentPane().add(textPane);
frame.setVisible(true);
}
}

testing suite with swing

I'm started to make a "testing suite" in java. I'm currently working on sentence completion type tests. Basically I have a text with placeholders, where the user should put in some text, and which will be evaluated later. I found out that by using FlowLayout I could fit the JLabels and JTextFields after each other. The problem is when a block of text is too long. It should span into multiple lines, and I'm not sure how to actually do that. And while that's okay, if I push a small text from the end of the line to a new line, but I'm still stuck if the whole text block is longer than the line width.
And I don't want to reinvent the wheel, so is there any opensource libraries for testing suites? My googlefu failed.
The best solution I've found to this problem is using Rob Camick's WrapLayout
WrapLayout is essentially an extension of FlowLayout which wraps the content when it can no longer fit horizontally.
Check out the linked blog above as it explains why your having the problems you are.
Updated
Another option would be to use JTextPane and insert fields into, for example...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;
public class TestText {
public static void main(String[] args) {
new TestText();
}
public TestText() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTextPane tp = new JTextPane();
tp.replaceSelection("Asd, asd, asd, fgh ");
addField(tp);
tp.replaceSelection(" more funky text here ");
addField(tp);
tp.replaceSelection(" and this must wrap on the edge. The color code of red is: #");
addField(tp);
tp.replaceSelection(". ");
tp.setEditable(false);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(tp));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
protected void addField(JTextPane tp) {
JTextField field = new JTextField(10);
field.setAlignmentY(0.75f);
tp.insertComponent(field);
}
});
}
}
Note, the editor itself is not editable, but the text fields are...

Java Eclipse text editor

Good day.
So I'm working on this project and I'm having one question.
I have an encyclopedia and I want to add a text editor.
I have a text and a scrollpanel and I want, when I select a sentence of my text and I press one button, to change the font, make the text bold, italic, underlined etc. How can I do that?
My code looks like this, the text.txt is a text file with "aaaa" in it.
package test;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Rectangle;
import javax.swing.JFrame;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class test extends JFrame {
private static final long serialVersionUID = 1L;
JFrame test = new JFrame("test");
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
test frame = new test();
frame.setVisible(false);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public test() {
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
setBounds(new Rectangle(0, 0, 0, 0));
getContentPane().setLayout(null);
test.setName("frame");
test.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
test.setBounds(300,0,800,800);
test.setResizable(false);
test.getContentPane().setLayout(null);
JScrollPane text = new JScrollPane();
text.setBackground(Color.DARK_GRAY);
text.setBounds(0, 0, 500, 400);
getContentPane().add(text);
JTextArea textarea = new JTextArea();
setBackground(Color.WHITE);
textarea.setEditable(false);
textarea.setWrapStyleWord(true);
textarea.setLineWrap(true);
try{
FileInputStream fstream = new FileInputStream("D:\\Facultate\\anul 2\\Java Workspace\\test\\src\\text.txt");
DataInputStream in = new DataInputStream(fstream);
Reader reader = new InputStreamReader(in);
textarea.read(reader, fstream);
}catch(Exception e){System.err.println("Error: " + e.getMessage());}
text.setViewportView(textarea);
}
}
From the documentation: "A JTextArea is a multi-line area that displays plain text." So if you want different fonts, etc. in one area, you'll have to use another control, probably RTFEditorKit
There is an amazing and Free Text Editor for Java. You can find it at
Download a ready-to-use CKEditor package that best suits your needs.
It's a product distributed by Amazon Web Services.

How to set text above and below a JButton icon?

I want to set text above and below a JButton's icon. At the moment, in order to achieve this, I override the layout manager and use three JLabel instances (i.e. 2 for text and 1 for the icon). But this seems like a dirty solution.
Is there a more direct way of doing this?
Note -I'm not looking for a multi-line solution, I'm looking for a multi-label solution. Although this article refers to it as a multi-line solution, it actually seems to refer to a multi-label solution.
EXAMPLE
import java.awt.Component;
import java.awt.FlowLayout;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public final class JButtonDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI(){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(new JMultiLabelButton());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static final class JMultiLabelButton extends JButton
{
private static final long serialVersionUID = 7650993517602360268L;
public JMultiLabelButton()
{
super();
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(new JCenterLabel("Top Label"));
add(new JCenterLabel(UIManager.getIcon("OptionPane.informationIcon")));
add(new JCenterLabel("Bottom Label"));
}
}
private static final class JCenterLabel extends JLabel
{
private static final long serialVersionUID = 5502066664726732298L;
public JCenterLabel(final String s)
{
super(s);
setAlignmentX(Component.CENTER_ALIGNMENT);
}
public JCenterLabel(final Icon i)
{
super(i);
setAlignmentX(Component.CENTER_ALIGNMENT);
}
}
}
There is not way to split the text between the top/bottom of a JButton. This would involve custom painting.
Since I'm not sure of your exact requirement I'll just through out a few random ideas:
You can use a JButton with text & icon. There are methods in the API that allow you to controal where text is positioned relative to the icon. Then you would need a second label for the other line of text. Basically the same as you current solution but you only need two labels.
You could use the Text Icon and Compound Icon classes to create 1 Icon out of 3 separate Icons. Then you can just add the icon to a button.
Use a JTextPane. Its supports an insertIcon() method. So you could add a line of text, add the icon and then add the other line of text. You can play with the paragraph attributes of the text pane to align the text horizontally within the space if you don't want the text left justified. You can also play with the background color to make it look like a label.
Example using the CompoundIcon:
import java.awt.*;
import javax.swing.*;
public final class JButtonDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JButton button = new JButton();
CompoundIcon icon = new CompoundIcon(CompoundIcon.Axis.Y_AXIS,
new TextIcon(button, "Top Label"),
UIManager.getIcon("OptionPane.informationIcon"),
new TextIcon(button, "Bottom Label"));
button.setIcon( icon );
button.setFocusPainted( false );
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add( button );
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
you have two four options
1) use JLabel + Icon + Html (<= Html 3.2)
2) use XxxButtonUI and override all required methods from API
3) JLayeredPane with translucency???, another Layout with translucency, as JLabel or JComponent to the JButton,
4) there are around lots of Graphics SW that can to prepare Background as *.jpg for Icon, then is very simple to change whatever by Event, Action or actual setting for JButton
not correct way is looking for JLabel + Whatever instead of JButton, I think that is halfsized workaround
Find another LayoutManager, here: http://download.oracle.com/javase/tutorial/uiswing/layout/visual.html

Categories