How to make only the next line of JTextArea (+JScrollPane) editable - java

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.

Related

Stopping a JTextPane from receiving new line feeds

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.

Components choice for chat gui

In fact I just start actively practise swing in order my theoretical knowledge comes handy :) I've already done a lot for chat GUI implementation but at the end stuck with some issues. So I decided to rework chat GUI from scratch, but I need to make right choice of components for it.
At first, I must say that there's no "input" functionality in the first implementation.
My current chat implementation consists of the following components:
JScrollPane to scroll up/down messages
Each message is the JPanel with JLabel inside. JLabel works great with HTML so it is easy to change smiles tokens to . Also message constructs from two strings: sender's name and message. So again, support of HTML in JLabel lets us mark sender's name with tag.
The reasons I think I'm stuck and chat GUI should be reworked from scratch:
JLabel works with HTML but if you use JScrollPane.HORIZONTAL_SCROLLBAR_NEVER, there's no more words wrap in it. Replacement of JLabel with JTextArea isn't good idea, cause JTextArea doesn't work with HTML.
There's no possibility to scroll down scrollbars automatically when new message is added. At least I didn't manage to do it.
It is difficult to control amount of components (JPanels with JLabels) to delete old ones when new message received from server. Otherwise it is possible to create hundreds of JPanels with JLabels in ten-fifteen minutes in an active chat. WeakReference is good here but usage of JPanel + JLabel for each message is bad design from the very beginning.
There're some other issues but they're not so critical and couldn't influence "rework decision".
I'd greatly appreciate if you could give a hint what components do suit well for such application like chat based on "reasons" described above.
Your design is bad and you should feel bad.
Try to copy some text from a bunch of JLabel displayed contiguously.
Just use a JTextPane or something like that! This function is from a program of mine, in a class that extends JTextPane, it adds some text at the end, with some peculiar style. You can modify it to do whatever you need.
public void append(String append,Color fg,Color bg, boolean bold,boolean italic, boolean underline) {
try {
// Get the text pane's document
StyledDocument doc = (StyledDocument)this.getDocument();
// The color must first be wrapped in a style
Style style = doc.addStyle("StyleName", null);
StyleConstants.setForeground(style, fg);
StyleConstants.setBackground(style,bg);
StyleConstants.setBold(style,bold);
StyleConstants.setItalic(style,italic);
StyleConstants.setUnderline(style,underline);
// Insert the text at the end of the text
doc.insertString(doc.getLength(), append, style);
} catch (Exception e) {
e.printStackTrace();
}
this.setCaretPosition (this.getDocument().getLength()-1);
}

Getting a Swing to read input without a submit button

This is for an assignment so responses should not contain the code written for me.
I have written a program that is essentially an auto-complete program. It takes a word and returns the best matches.
I am trying to write a front end for it in swing(which I have no experience in) and want my front end to do the following: I want the input box to constantly be reading for user input, feeding that value to the other program, and returning the matches immediately in a drop down box, as, say, Google does. I can't seem to find any information on how to do this, all the intro tutorials use a submit button.
Can anyone explain to me how this would be done, or point me to a resource that could explain it? Again, please don't write the code for me, I don't want to unwittingly cheat on my assignment.
If you are using a JTextField, you could register a document listener on it.
If your input box is a JTextField, you can add a DocumentListener (this is a good tutorial) to capture character entries.
I think that no one from answerers ..., I'm only about Don't reinvent the wheel
1) use JTable with one (or two if is about Dictionary) Column and with basic implmentation for Sorting and Filtering (example with filtering from JTextField is in the Tutorial), JTable could be most complex from JComponents and there is everything (quite easilly) possible
2) use AutoComplete JComboBox / JTextField
3) use SwingX Decorator with JXList or JXTable
4) if you needed redirect output to the separate window then use JDialog / JWindow for popup window
One approach could be:
Attach a handler to detect a key press on the text box.
Grab the text from the box, and construct a "lookup" event which is runnable and submit this to some form of service which will dispatch it at some point in the future (hint: ExecutorService, Future)
Save this handle, and if the key press event happens again, cancel the previous and submit a new one.
When the event executes in the future and returns the result, popup a panel which displays the list of items.

How can I create an AutoComplete popup in a JTextPane in Java?

I am creating a SQL editor. I am using JTextPane for the editor. I want to implement AutoCompletion for table name etc. like Eclipse.
I think the appropriate class for displaying info on top of another component is JPopupMenu, which already handles layering correctly to display itself. JPopupMenu has a show() method that takes its 'parent' component as an argument, and it will show itself in that component's coordinate space. Since you want to display a selection of terms for the user to choose from, a menu seems appropriate.
To check for text changes, you'd add a DocumentListener to the document that's wrapped by the JTextPane; you can access it using getDocument().
To find out where the cursor (actually, the caret) is, you can use getCaretPosition(). That returns the caret's position within the text stream as an int. You can use modelToView() to translate that position to actual (x,y) coordinates. That in turn will tell you where to show your menu.
You can use addKeyListener() to catch keyboard events on your JTextPane, like hitting Ctrl-Space.
The combination of all that should allow you to do what you're looking to do.
You can also use http://fifesoft.com/autocomplete/. You can install it on any JTextComponent.
For things like this you probably should consider layered panes so your auto-complete suggestions appear in the correct place and z-order.
Furthermore you will have to look for changes in the JTextPane to know when the user is typing and you will need a parser that understands what is typed so you can offer the feature only at appropriate points.
It's not quite clear what exactly your problem is and what you got so far.
I achieved this by adding a key listener to the JTextPane and checking for CTRL + Space keystrokes. When the appropriate key combo was detected the listener went off and looked up the list of possible matches based on the characters directly to the left of the cursor at the time of the key press and found the best matches and displayed them to the user in a JPopup. If there was an exact match then it simply replaced the partial text with the match. If no matches were found an option was given to the user to add the text that they had already typed, edit it and record it into the list of acceptable data.
We use jide. They have a lot of components that help you do this kind of thing really easily

Java Swing, textarea as input/output?

I want to load up a window using the java swing, something like this
However I want to be able to use it for text input also not just to dump data into it..
any idea how to do it?
JTextAreas are editable by default, so input is trivial. Just put one into a test UI and see for yourself.
From a design perspective, using the same JTextArea for both input and output strikes me as unwise. The only example I can think of is a shell interface, and that imposes stronger limits on how input and output works than a JTextArea will provide out of the box.
I'm not sure if I got the point of your question, but you can get the text the user has typed in using the getText() method:
JTextArea ta = new JTextArea();
String input = ta.getText();
Check out this Sun toturial:
http://java.sun.com/docs/books/tutorial/uiswing/components/textarea.html
In particular, scroll down to the "TextAreaDemo" example.

Categories

Resources