Disable modify\delete JTextArea content (but not insert) - java

I have JTextArea component and I need to disable modify\delete current content in component by users. Users may only add\insert some text at the end, but setText method must work as usual.
tnx

I need to disable modify\delete current content in component by users.
textArea.setEditable( false );
Users may only add\insert some text at the end, but setText method must work as usual.
You should have an "Add Text" button that will take text from a separate text field and then append the text to the Document using the append(...) method of the JTextArea.

Could you post an example of what you already have?
To clarify, if you want users to be unable to certain things, you may need to re-insert the original text manually. I'm unsure of the editor used by a JTextArea, but you could try overriding that.
Horrific code I'm coming up with on the spot incoming, you can probably do this much easier:
private static String mand = "mandatory.";
private static JTextArea test = new JTextArea(mand);
public static String getMand() {
return mand;
}
public static JTextArea getTest() {
return test;
}
public static void setMand(String mand2) {
mand = mand2;
}
public static void setTest(JTextArea test2) {
test = test2;
}
getTest().addKeyListener(new KeyListener() {
#Override
public void keyPressed(KeyEvent arg0) {
// do nothing
}
#Override
public void keyReleased(KeyEvent arg0) {
// do nothing
}
#Override
public void keyTyped(KeyEvent arg0) {
if(getTest().getText().startsWith(getMand())) {
System.out.println("good, text still present");
setMand(test.getText());
} else {
getTest().setText(getMand());
}
}
});
WARNING :: if the user makes any mistakes in adding information to the JTextArea, the code will not allow the user to fix these mistakes.
Tested successfully under JDK (/JRE) 7.

Related

What is a good way to display status of a file using Swing

I want to do the following and I would need some suggestions on what is the best way to do it.
I have a JList which displays the files that the user adds by clicking add (+) button and removes the files when the user clicks remove (-) button. With each added file, I want to associate an icon which should indicate the status of the file. For example, if the user has only added the file and not run the file (I have another JButton for running the application with the selected file), then this icon should be red and once the user runs it, this icon should change to green. Also, if the user removes the file by clicking the (-) button, it should remove the icon associated with that particular file too. Below is a pictorial representation of what I want.
I was thinking of associating a ImageIcon with each added file but I am not sure how to change its appearance to display the status. I am also not sure how the ImageIcon can be removed when the file is removed. Is there any other way (other than ImageIcon) to do it? Any help/suggestions are appreciated.
In programming, data is king. How that data get's represented should not be of consideration to the data, that's the domain/responsibility of the UI/view layers.
This is often represented by the model-view-controller pattern
In your example, you have two pieces of (basic) information. A file and a status (not run, run, deleted), you want to combine this information as "data". In Java, that typically means a Plain Old Java Object (or Pojo)
Because the status only has a limited number of possibilities, we can use a enum to represent it, and thereby restricting the valid values
public enum FileStatus {
NOT_RUN, RUN, DELETED;
}
And then we can create our own pojo...
public class FileOperation {
private File file;
private FileStatus status;
public FileOperation(File file, FileStatus status) {
this.file = file;
this.status = status;
}
public FileOperation(File file) {
this(file, FileStatus.NOT_RUN);
}
public File getFile() {
return file;
}
public FileStatus getStatus() {
return status;
}
public void setStatus(FileStatus newStatus) {
if (status == newStatus) {
return;
}
this.status = newStatus;
}
}
Now, when we want to know the status of the file, we know where to get it.
But what about the JList? You ask, good question. What we really want is some way that the JList can be informed when the status of any FileOperation object changes.
Now, you could iterate over the ListModel, but that's not a very clean solution, a better solution is to allow the FileOperation to generate events when it changes and have the ListModel listen for them and take it's own action.
This is a basic concept of an observer patternÆ’
There's a number of ways you might do this, but I'm lazy, so I'm just going to use the available property change API
public class FileOperation {
private File file;
private FileStatus status;
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
public FileOperation(File file, FileStatus status) {
this.file = file;
this.status = status;
}
public FileOperation(File file) {
this(file, FileStatus.NOT_RUN);
}
public File getFile() {
return file;
}
public FileStatus getStatus() {
return status;
}
public void setStatus(FileStatus newStatus) {
if (status == newStatus) {
return;
}
FileStatus oldStatus = status;
status = newStatus;
propertyChangeSupport.firePropertyChange("status", oldStatus, status);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
}
And now we need a ListModel which can respond to it...
public class FileOperationListModel extends AbstractListModel<FileOperation> {
private List<FileOperation> items = new ArrayList<FileOperation>(25);
private PropertyChangeListener handler = new PropertyChangeHandler();
public void add(FileOperation fo) {
fo.addPropertyChangeListener(handler);
int size = items.size();
items.add(fo);
fireIntervalAdded(this, size, size);
}
public void remove(FileOperation fo) {
int index = items.indexOf(fo);
if (index < 0) {
return;
}
fo.removePropertyChangeListener(handler);
items.remove(fo);
fireIntervalRemoved(this, index, index);
}
#Override
public int getSize() {
return items.size();
}
#Override
public FileOperation getElementAt(int index) {
return items.get(index);
}
public class PropertyChangeHandler implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (!(evt.getSource() instanceof FileOperation)) {
return;
}
FileOperation fo = (FileOperation) evt.getSource();
int index = items.indexOf(fo);
fireContentsChanged(FileOperationListModel.this, index, index);
}
}
}
Now, the final piece of the puzzle, is you're going to need a custom ListCellRenderer which can display the information you want.
For that, you're going to have to start by reading How to use lists and Writing a Custom Cell Renderer

How to show non-printable characters in SWT a text widget

How is it possible to display non-printable characters in an SWT StyledText widget in a way it's done by Swing with an empty square?
To replace all occurrences with a symbol via regex in the source string can't be the solution because copy & paste with the original codepoint won't be possible anymore.
The best way might be to intercept the text rendering and replace them there, but that seems to open Pandora's box...
Edit 1:
The control characters, it's all about, are characters that are normally just skipped and not shown by the editor like HOP (U+0081)
For an E4 RCP application I have attached some code to start with.
Basically is uses the IEventBroker to add/remove the painter of the TextViewer by means of a button.
The StyledText can be obtained from
styledText = tv.getTextWidget();
as commented above
import org.eclipse.jface.text.WhitespaceCharacterPainter;
public class TheEditor{
#Inject MPart thePart;
private WhitespaceCharacterPainter whitespaceCharacterPainter;
#PostConstruct
public void postConstruct(Composite parent) {
TextViewer tv = new TextViewer(parent, SWT.MULTI | SWT.V_SCROLL |SWT.H_SCROLL);
whitespaceCharacterPainter = new WhitespaceCharacterPainter(tv);
tv.addPainter(whitespaceCharacterPainter);
whitespaceCharacterPainter.deactivate(true);
}
#Inject
#Optional
public void updatePartByWSButton(#UIEventTopic(EventConstants.WHITE_CHARACTERS_STATUS) boolean newButtonStatus) {
final MElementContainer<MUIElement>container = thePart.getParent();
if (thePart.equals((MPart)container.getSelectedElement())){
wsToolBarButtonStatus = newButtonStatus;
if(wsToolBarButtonStatus){
this.whitespaceCharacterPainter.paint(IPainter.CONFIGURATION);
}
else{
whitespaceCharacterPainter.deactivate(true);
tv.removePainter(whitespaceCharacterPainter);
}
}
}
}
Handler Class
public class WhitespaceCharactersHandler {
boolean status;
#Execute
public void execute(final MToolItem item, IEventBroker broker) {
if (item.isSelected()){
status = true;
}
else{
status = false;
}
broker.post(EventConstants.WHITE_CHARACTERS_STATUS, status);
}
}
Contants interface:
public interface EventConstants {
String WHITE_CHARACTERS_STATUS = "WHITE-CHARACTERS-STATUS";
}

Restrict TextArea using Unicode with Java

I have a TextArea that I am trying to restrict user inputs to allow only IP addresses format in that Area. So I thought of only allowing digits and decimal points. For multiple IPs, One IP per line, so the TextArea needs to accept new lines. For the most part what I have below is working except for delete. I can't delete any entry even if I am using the associate Unicode. I am running MAC OS 10, not sure if it makes any difference or not but the info is out there just in case.
public class RestrictIpInputTextArea extends TextArea {
#Override
public void replaceText(int i, int il, String string){
if(string.matches("[0-9_\\u000A_\\u232B_\\u0008_\\u2421_._\\u007F]") || string.isEmpty()){
super.replaceText(il, il, string);
}
}
#Override
public void replaceSelection(String string) {
super.replaceSelection(string);
}
I was able to find out the solution for it. Visit the link below for more reference.
http://docs.oracle.com/javafx/2/ui_controls/custom.htm
However, I still want to explore TextFormatter function deployed in JavaFX 8U40
public class numericValue extends TextArea {
#Override
public void replaceText(int start, int end, String text) {
String old = getText();
if (text.matches("[0-9_._\\u000A]*")) {
super.replaceText(start, end, text);
}
}
#Override
public void replaceSelection(String text) {
String old = getText();
if (text.matches("[0-9_._\\u000A]*")) {
super.replaceSelection(text);
}
}
}

How to add properly UiHandler for BlurEvent in GWT?

Normally if we have some textField in GWT we can add a BlurHandler by the following code:
textField.addBlurHandler(new BlurHandler() {
#Override
public void onBlur(BlurEvent event) {
//what we need
}
});
But if we use UiBinder and our textField is annotated by #UiField and it is mentioned in our ui.xml file we can add BlurHandler by this code as well:
#UiHandler("textField")
protected void createBlurHandler(BlurEvent event) {
}
I guess I am right here because it works like this. So, the question is, can we actually define BlurHandler inside ui.xml file?
For example, it is possible to add inputMaxLength and some other attributes there, does GWT has some possibility like onChange method or are these ways that I described the only possibilities?
I would like to have something like this:
<g:TextBox ui:field="textField" onBlur="methodName" />
Is it possible?
I am pretty sure what you are asking is not possible. The problem is that you wouldn't be able to use reflection to figure out which method you want to call. However you can extends the TextBox class and use that inside your template. The extended class could have it's own properties that can be set in the template. An example is as follows where I set the default test on my own DefaultTextBox.
public class DefaultTextBox extends TextBox {
/**
* The text color used when the box is disabled and empty.
*/
private static final String TEXTBOX_DISABLED_COLOR = "#AAAAAA";
private final String defaultText;
public #UiConstructor
DefaultTextBox(final String defaultText) {
this.defaultText = defaultText;
resetDefaultText();
// Add focus and blur handlers.
addFocusHandler(new FocusHandler() {
#Override
public void onFocus(FocusEvent event) {
getElement().getStyle().clearColor();
getElement().getStyle().clearFontStyle();
if (defaultText.equals(getText())) {
setText("");
}
}
});
addBlurHandler(new BlurHandler() {
#Override
public void onBlur(BlurEvent event) {
if ("".equals(getText())) {
resetDefaultText();
}
}
});
}
public String getDefaultText() {
return defaultText;
}
#Override
public void setText(String text) {
if (text == null) {
super.setText(getDefaultText());
} else {
getElement().getStyle().clearColor();
getElement().getStyle().clearFontStyle();
super.setText(text);
}
}
public String getText() {
return super.getText();
}
/**
* This is override so that the editor framework will not get the default
* value but the actual null value when the default text is in the box.
*/
#Override
public String getValue() {
try {
return getValueOrThrow();
} catch (ParseException e) {
return null;
}
}
#Override
public void setValue(String value) {
setText(value);
}
/**
* This is overridden from the parent class because this is
* how the editor gets the value.
*/
public String getValueOrThrow() throws ParseException {
if (defaultText.equals(super.getValueOrThrow())) {
return null;
}
return super.getValueOrThrow();
}
/**
* Reset the text box to the default text.
*/
public void resetDefaultText() {
setText(defaultText);
getElement().getStyle().setColor(TEXTBOX_DISABLED_COLOR);
getElement().getStyle().setFontStyle(FontStyle.ITALIC);
}
}
Then in the template you can set properties like this.
<w:DefaultTextBox defaultText="name" ui:field="nameTextBox" />
This will also work with setters, you can set properties without having to use the #UiConstructor but in my case I wanted to make sure that there was no empty constructor for this class.

How do I update a ColourHighlighter (swingx) when the predicate has changed

I have a class called ErrorHighlighter which gets notified anytime a property called errorString is changed. Based on this propertychangeevent I update the HighLighterPredicate to highlight a particular row with a red background.
ErrorHighlighter receives the propertychangeevent, it also changes the HighlighterPredicate, but the table row does not get updated with red background.
I also update the tooltip of the row. That does not get reflected either.
Please see the code below. Could someone please help?
public class ErrorRowHighlighter extends ColorHighlighter implements PropertyChangeListener {
private Map<Integer, String> rowsInError;
private SwingObjTreeTable<ShareholderHistoryTable> treeTable;
public ErrorRowHighlighter(SwingObjTreeTable<ShareholderHistoryTable> treeTable) {
super(CommonConstants.errorColor, null);
this.treeTable = treeTable;
rowsInError=new HashMap<Integer, String>();
setHighlightPredicate(new HighlightPredicate() {
#Override
public boolean isHighlighted(Component renderer, ComponentAdapter adapter) {
if(rowsInError.containsKey(adapter.row)){
return true;
}
return false;
}
});
this.treeTable.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
int row=ErrorRowHighlighter.this.treeTable.rowAtPoint(e.getPoint());
if(rowsInError.containsKey(row)){
ErrorRowHighlighter.this.treeTable.setToolTipText(rowsInError.get(row));
}else{
ErrorRowHighlighter.this.treeTable.setToolTipText(null);
}
}
});
}
public void highlightRowWithModelDataAsError(ShareholderHistoryTable modelData){
int indexForNodeData = treeTable.getIndexForNodeData(modelData);
if(indexForNodeData>-1){
rowsInError.put(indexForNodeData, modelData.getErrorString());
updateHighlighter();
}
}
public void unhighlightRowWithModelDataAsError(ShareholderHistoryTable modelData){
int indexForNodeData = treeTable.getIndexForNodeData(modelData);
if(indexForNodeData>-1){
rowsInError.remove(indexForNodeData);
updateHighlighter();
}
}
public void updateHighlighter(){
treeTable.removeHighlighter(this);
treeTable.addHighlighter(this);
}
#Override
public void propertyChange(PropertyChangeEvent evt) {
ShareholderHistoryTable sourceObject= (ShareholderHistoryTable) evt.getSource();
if(StringUtils.isNotEmpty(sourceObject.getErrorString())){
highlightRowWithModelDataAsError(sourceObject);
}else{
unhighlightRowWithModelDataAsError(sourceObject);
}
}
}
This looks like a mistake on my part. The method treeTable.getIndexForNodeData() actually returns back the index of the row by doing a pre-order traversal of the underlying tree data structure. This includes a root node that is not being displayed on the jxtreetable. Hence I needed to minus 1 from the index
int indexForNodeData = treeTable.getIndexForNodeData(modelData)-1;
This fixed the problem for me. I am leaving the post rather than deleting it if anyone wants to look at an example of a ColorHighlighter and a property change listener.

Categories

Resources