I want to highlight the lines which are errors while validating, I am currently using jtextarea, looked into jtextpane and styles, i need some suggestions in implementing like the below way. Should i have to take jtextarea or jtextpane or any other best and easy option? thanks
private void validate(String text){
lines = text.split("\n");
for(String line : lines){
if(line.substring(0, 1).equals("")){
//want to highlight the entire line in red color
} else {
//remove the highlight
}
}
}
Use
textarea.getHighligter().addHighlight()
See the doc DefaultHighlighter and Demos and Usage of DefaultHighlighter
JTextArea will certainly not work as it only supports plain text. You will need a JTextPane. A handy overview (as I always forget which one does what) can be found in the Swing tutorial
For your validation, I would add a DocumentListener which validates the input and changes the color depending on the state.
Related
I have a display text area in my JavaFX app.
It has several methods for appending strings to it.
What I want is for any newly appended text to have some kind of feedback so the user is more visually aware of the new text being displayed.
Ideally what I would like is one of the following, but am very open to other suggestions:
The appended text is 'typed out' as if someone were typing it into the display text area itself. Or..
Some kind of highlighting of the new text as it appears.
Although again, I'm open to suggestions!
Thank you.
As suggested in Highlighting Strings in JavaFX TextArea, you can select the new text.
Assuming the text area is not editable, and you are only ever appending to the end of the existing text, you can do:
textArea.textProperty().addListener((obs, oldText, newText) -> {
if (newText.length() > oldText.length()) {
Platform.runLater(() ->
textArea.selectRange(oldText.length(), newText.length()));
}
});
If your text area is editable, or you are using it more generally, then you can do something similar each time you append text. For example:
String message = ... ;
textArea.positionCaret(textArea.getLength());
textArea.appendText(message);
textArea.extendSelection(textArea.getLength());
Maybe try to use RichTextArea (https://github.com/TomasMikula/RichTextFX), then is many possibilites to show your text in different ways.
I want my JTextPane to have some functionality when the user presses Enter and not just change the line. Now I understand how to implement the functionality I want, but I still can't negate the line feed from pressing Enter. I have tried the following but it doesn't seem to work, the new line will be created anyway.
To give a better idea of what I'm trying to achieve here, the textpane is supposed to contain a certain filepath, so I want the user to be able to scroll only horizontaly and not add new lines verticaly. Is the JTextPane component suitable for this use?
locationPane = new JTextPane();
locationPane.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent arg0) {
if(arg0.getExtendedKeyCode() == KeyEvent.VK_ENTER){
locationPane.setText(locationPane.getText().substring(0, locationPane.getText().length()));
}
}
});
KeyListener is never a suitable soution for text components. Instead you should be using a DocumentFilter to filter out things you don't want to be added to the underlying Document.
See Implementing a Document Filter and DocumentFilter Examples for more details
You could also alter the insert-break key binding, changing the behaviour or taking additional action.
See this example for more details
the textpane is supposed to contain a certain filepath, so I want the user to be able to scroll only horizontaly and not add new lines verticaly. Is the JTextPane component suitable for this use?
I would suggest there are better options.
If you only have a single line of text then just use a JTextField. To handle the Enter key you can add an ActionListener to the text field.
If you do need multiple line then I would suggest you could use a JList.
So im creating a server, and that works great, however I am a bit stuck on the GUI. You see, I would like it to look just like Command Prompt, where only the next line is editable, and it does not let you delete any other text. So right now I have:
JTextArea ta = new JTextArea();
JScrollPane sp = new JScrollPane(ta);
Then the frame stuff...
f.setTitle("Server");
f.setBounds(ss.width - 600, 50, 550, 350);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);//added window listener so closes socket connection first
f.setAlwaysOnTop(true);
Then adding it:
f.add(sc);
jt.setBackground(Color.BLACK);
jt.setForeground(Color.WHITE);
//jt.setEditable(false);
Finally, the method I use to output to the TextArea:
public static void append(String text) {
jt.append(text);
jt.append("\n\n"+System.getProperty("user.name")+" / "+getIp()+" > ");
jt.setCaretPosition(jt.getDocument().getLength());
}
Now I need to assign a String to what the user types into the JTextArea after they press enter:>?
jt.addActionListener(...{
public void ActioEvent(ActionEvent e){
String text = JTextArea.getLines().getLastLine().getText().replace(System.getProperty("user.name")+" / "+getIp()+" > ", "");
}
});
Maybe something like that?
Then I need to have it so that only the part after the ">" is editable?
The way to do this is with a DocumentFilter. This is a fairly obscure and little-used part of Java, and is far from easy to use. However it allows you to insert a DocumentFilter between the UI (where rich text content is edited) and the underlying model (the content). You pass all the 'insert' and 'remove' operations through the filter, which can either accept, refuse or modify them. You can code the filter to only permit modifications to the command line, and not to the prompt.
As I say, this is a pretty hard piece of coding, and the Document/DocumentFilter structure has a lot of complexity that your particular application doesn't need. However it does provide you with the facilities you need.
There is a tutorial in the standard Java doc pages, but not an advanced one, and very few examples that I know of are out there on the web.
ProtectedTextComponent (thanks camickr) provides an example of how to do something similar.
Use a Collection a JTextField.
Let the user type on a JTextField, and once he presses enter, move the control to the next JTextField while making the above JTextField uneditable and also remove the JScrollPane from it.
Hope this helps.
I also agree that the JTextArea/JTextField approach is the common and simpler approach.
However if you want to complicate your life a little then you can check out Protected Text Component which will do most of the logic for you.
The current implemtation of the ProtectedDocument only allows you to add protection to the Document, not remove it so the first thing you will need to do is add a method to "Clear" all the protect pieces of text. This is easy enough, you just clear the entries in the Map used by the class.
Next you will need to replace the default "Enter" Action used by the JTextPane. You do this by playing with the Key Bindings of the text area. See Key Bindings for some basic information. In your custom Action you would first need to invoke the newly created "clear(...)" method. Then you would add you text to the text area. Finally you would protect all the text but the last "x" number of characters.
I am creating a Help System that uses links (a JButton extension) that expand and collapse subpanels with JLabels in them. The links and the collapsible panels work, but I'm having trouble implementing my find dialog. I want to be able to highlight parts of the text for which the user searches. I think my use of text attributes to underline the text in the links is messing with my ability to highlight the parts of the text, but I'm not sure how to do it differently. Here's the code for my Link class which my links subclass:
public abstract class Link extends JButton {
private static final int SPACE = 5;
private static final Color TEXT_COLOR = Color.BLUE;
public Link(String text) {
super(text);
setBorder(BorderFactory.createEmptyBorder(SPACE, SPACE, SPACE,
2 * SPACE));
setContentAreaFilled(false);
setFocusable(false);
setForeground(TEXT_COLOR);
Map<TextAttribute, Integer> underlineAttribute =
new HashMap<TextAttribute, Integer>();
underlineAttribute.put(TextAttribute.UNDERLINE,
TextAttribute.UNDERLINE_ON);
setFont(getFont().deriveFont(underlineAttribute));
}
}
How can I implement highlighting text in my links without getting rid of the underlining? Do I need to change them to subclass something else?
One approach is to use HTML formatting for the button text. Of course, the path of least surprise for the end user would be if the buttons looked like buttons and the links looked like links (i.e. not buttons).
Should I subclass something else for the links?
For a link I'd generally use a JTextField, as shown on my answer to How to change JButton?
E.G.
I have a JScrollPane that holds a JLabel using the following code:
//Create TEXT LOG JPanel
textLogPane = new JScrollPane(logLabel);
textLogPane.setPreferredSize(textLogPaneDim);
//textLogPane.setOpaque(true);
textLogPane.setBorder(BorderFactory.createLineBorder(Color.BLACK));
textLogPane.getViewport().setBackground(Color.DARK_GRAY);
The JLabel, logLabel, is represented by a string with an HTML encoding using for carriage returns. I display certain images based on the contents of certain lines and I would like to be able to scroll the JScrollPane, textLogPane, to show that line whenever I am displaying that graphic. I know the contents of the line that I want to display but I can't seem to figure out how to get it to scroll down(or up) to the relevant line.
If need be I can change to something other than a JLabel as long as I can keep the HTML encoding and have it look just like multiple lines of text.
Sorry if this is a repeat I tried searching but couldn't find any results.
Thanks
You can do some custom maths and use scrollRectToVisible() in your viewport. I don't know how to compute the rect of a specific line in your JLabel. A better solution would be to stick your strings into a JList instead, perhaps with a custom renderer for the html, and use
list.ensureIndexIsVisible(list.getSelectedIndex());
You don't use "carriage returns" in HTML, you use "br" tags.
I would suggest you should probably be using a JTextPane for multiline text. I also find it easier to not use HTML, but instead to add strings with attributes. You can also insert icons into a JTextPane.
Read the section from the Swing tutorial on Using Text Components for a working example.